Questions d'expansion de la structure des données

Inversion de liste chaînée unique

Cette question nécessite l'implémentation d'une fonction pour inverser une liste donnée à chaînage unique.
Définition de l'interface de fonction :

List Reverse( List L );

La structure de la liste est définie comme suit :

typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /* 存储结点数据 */
    PtrToNode   Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

L est une liste chaînée unique donnée, et la fonction Reverse doit renvoyer la liste chaînée inversée.
Exemple de procédure de test d’arbitre :

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表 */

List Reverse( List L );

int main()
{
    List L1, L2;
    L1 = Read();
    L2 = Reverse(L1);
    Print(L1);
    Print(L2);
    return 0;
}

/* 你的代码将被嵌在这里 */

Exemple de saisie :

5
1 3 4 5 2

Échantillon de sortie :

1
2 5 4 3 1

Code:

List Reverse( List L )
{
    List p, q;
    p = L;
    L = NULL;
    while (p)
    {
        q = p;
        p = p->Next;
        q->Next = L;   
        L = q;
    }
    return L;
}

expliquer:
Stockez la table d'origine en tant que table p et laissez la table d'origine L vide. Parcourez la liste à chaînage unique, tant que p n'est pas vide, utilisez q pour enregistrer la position actuelle, puis déplacez le pointeur p vers l'arrière. Attribuez d'abord L avec une valeur NULL à q->next, puis la valeur suivante pointée par l'emplacement du premier q est NULL, puis attribuez q à L, puis le pointeur de tête de cette liste chaînée est L.
Par analogie, q->next est toujours placé devant L, puis L = q est utilisé pour échanger le pointeur de tête vers l'arrière.

Ensemble d'opérations de table de séquence

Cette question nécessite la mise en œuvre de l’ensemble d’opérations de la table de séquence.
Définition de l'interface de fonction :

List MakeEmpty(); 
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

La structure de la liste est définie comme suit :

typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last; /* 保存线性表中最后一个元素的位置 */
};

La définition de chaque fonction opérationnelle est la suivante :

List MakeEmpty() : crée et renvoie une liste linéaire vide ;

Position Find (List L, ElementType X) : renvoie la position de X dans la liste linéaire. S'il n'est pas trouvé, renvoyez ERROR ;

bool Insert (List L, ElementType X, Position P) : insérez X à la position P et retournez true. Si l'espace est plein, imprimez "FULL" et renvoyez false ; si le paramètre P pointe vers une position illégale, imprimez "ILLEGAL POSITION" et renvoyez false ;

bool Supprimer (Liste L, Position P) : supprime l'élément à la position P et renvoie vrai. Si le paramètre P pointe vers une position illégale, imprimez "POSITION P EMPTY" (où P est la valeur du paramètre) et renvoyez false.
Exemple de procédure de test d’arbitre :

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 5
#define ERROR -1
typedef enum {false, true} bool;
typedef int ElementType;
typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last; /* 保存线性表中最后一个元素的位置 */
};

List MakeEmpty(); 
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

int main()
{
    List L;
    ElementType X;
    Position P;
    int N;

    L = MakeEmpty();
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        if ( Insert(L, X, 0)==false )
            printf(" Insertion Error: %d is not in.\n", X);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else
            printf("%d is at position %d.\n", X, P);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &P);
        if ( Delete(L, P)==false )
            printf(" Deletion Error.\n");
        if ( Insert(L, 0, P)==false )
            printf(" Insertion Error: 0 is not in.\n");
    }
    return 0;
}

/* 你的代码将被嵌在这里 */

Exemple de saisie :

6
1 2 3 4 5 6
3
6 5 1
2
-1 6

Échantillon de sortie :

FULL Insertion Error: 6 is not in.
Finding Error: 6 is not in.
5 is at position 0.
1 is at position 4.
POSITION -1 EMPTY Deletion Error.
FULL Insertion Error: 0 is not in.
POSITION 6 EMPTY Deletion Error.
FULL Insertion Error: 0 is not in.

Code:

//创建并返回一个空的线性表
List MakeEmpty()
{
    List L;
    L = (List)malloc(sizeof(struct LNode)); //(1)注意结构体的名字并未重新定义,所以必须使用原始名称;(2)只开辟一个节点空间就行
    L->Last = -1;  //注意赋值是-1
    return L;
}

//返回线性表中X的位置。若找不到则返回ERROR
Position Find( List L, ElementType X )
{
    int flag = 0;
    int i;
    for (i=0;i<=L->Last;i++)
    {
        if (X == L->Data[i])
        {
            flag++;
            return i;
        }
    }
    if (!flag) return ERROR;
}


//将X插入在位置P并返回true。若空间已满,则打印“FULL”并返回false;如果参数P指向非法位置,则打印“ILLEGAL POSITION”并返回false
bool Insert( List L, ElementType X, Position P )
{
    if (L->Last == MAXSIZE-1) //因为要插入元素,所以必须比MAXSIZE少一位
    {
        printf("FULL");
        return false;
    }
    if (P > L->Last+1 || P < 0)  //P插入的位置可以是Last位置,但是不能是Last的下一位
    {
        printf("ILLEGAL POSITION");
        return false;
    }
    int i;
    for (i=L->Last+1;i>P;i--)
        L->Data[i] = L->Data[i-1];
    L->Data[i] = X;
    L->Last++;
    return true;
}


//将位置P的元素删除并返回true。若参数P指向非法位置,则打印“POSITION P EMPTY”(其中P是参数值)并返回false。
bool Delete( List L, Position P )
{
    if (P < 0 || P > L->Last)
    {
        printf("POSITION %d EMPTY",P);
        return false;
    }
    int i;
    for (i=P;i<L->Last;i++)
        L->Data[i] = L->Data[i+1];
    L->Last--;
    return true;
}

Je suppose que tu aimes

Origine blog.csdn.net/weixin_44236278/article/details/102466473
conseillé
Classement