Notes d'étude: Pile de structure de données Big Talk

Pile de structure de données Big Talk

Définition de pile

Une pile est une table linéaire qui n'insère et ne supprime qu'à la fin de la table. Une extrémité qui permet l'insertion et la suppression est appelée le haut de la pile et l'autre, le bas de la pile.

  • La pile est également appelée table linéaire dernier entré premier sorti, appelée structure LIFO
  • L'opération d'insertion de la pile consiste à pousser et à pousser dans la pile; l'opération de suppression de la pile éclate
typedef int SElemType; /*SElemType类型根据实际情况而定,这里假设为int*/
typedef struct
{
    
    
    SElemType data[MAXSIZE];
    int top; /*空栈top=-1,栈满etc*/
}SqStack;

Structure de stockage séquentiel de la pile

/*进栈操作 插入元素e为新的栈顶元素*/
Status Push(SqStack *S,SElemType e)
{
    
    
    if(S->top == MAXSIZE -1) /*栈满*/
    {
    
    
        return ERROR;
    }
    S->top++; /*栈顶指针增加一*/
    S->data[S->top] = e; /*将新插入元素赋值给栈顶空间*/
    return OK;
}
/*出栈操作:若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR*/
Status Pop(SqStack *S,SElemType *e)
{
    
    
    if(S->top == -1)
        return ERROR;
    *e=S->data[S->top]; /*将要删除的栈顶元素赋值给e*/
    S->top--; /*栈顶指针减一*/
    return OK;
}

Espace partagé à deux piles: utilisez un tableau pour stocker deux piles

  1. Techniques de conception pour le même type de pile
  2. top1 + 1 == top2 (pile pleine); pile 1 est une pile vide, top2 = 0, pile 2 est pleine; pile 2 est pile vide, top1 de pile 1 est n-1 et pile 1 est pleine.
/*两栈共享空间结构*/
typedef struct
{
    
    
    SElemType data[MAXSIZE];
    int top1; /*栈1栈顶指针*/
    int top2; /*栈2栈顶指针*/
}SqDoubleStack;

Status Push(SqDoubleStack *S,SElemType e, int stacklNumber)
{
    
    
    if(S->top1+1==S->top2) /*栈满*/
        return ERROR;
/* ****自增、自减
* ++i/--i, i自增/减1后再参与其他的运算;i++/i--,i参与运算后,i的值域再自增/减1*/
    if(stacklNumber==1)  /*若栈1有元素进栈*/
        S->data[++S->top1] = e; /*若栈1给top1+1后给数组元素赋值*/
    else if (stacklNumber ==2)/*若栈2有元素进栈*/
        S->data[--S->top2]=e; /*若栈2给top2-1后给数组元素赋值*/
    return OK;
}
/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR*/
Status Pop(SqDoubleStack *S,SElemType *e, int stackNumber)
{
    
    
    if (stackNumber == 1) {
    
    
        if (S->top1 == -1)  /*空栈,溢出*/
            return ERROR;
        *e = S->data[S->top1--]; /*栈1的栈顶元素出栈*/
    }
    if (stackNumber == 2)
    {
    
    
        if(S->top2==MAXSIZE)  /*空栈,溢出*/
            return ERROR;
        *e = S->data[S->top2++]; /*栈2的栈顶元素出栈*/
//        data[s--]等价于data[s];s--;
//        data[++s]等价于++s;data[s];
//        data[++s],++s入栈;先取出data[s],s--会删除栈顶的元素
    }
}

La structure de stockage en chaîne et la mise en œuvre de la pile

  1. La liste à liaison simple a un pointeur de tête, et le pointeur du haut de la pile est également nécessaire, alors placez le haut de la pile à la tête de la liste à liaison unique (nœud de tête -> haut de la pile)
  2. La pile de chaînes n'existe fondamentalement pas lorsque la pile est pleine; pour une pile vide, la liste liée a initialement défini le pointeur de tête pour pointer vers vide, puis le vide de la pile de chaînes est top = NULL
typedef struct StackNode
{
    
    
    ElemType data;
    struct StackNode *next;
}StackNode, *LinkStackPtr;

typedef struct LinkStack
{
    
    
    LinkStackPtr top;
    int count
}LinkStack;
/*
进栈操作:单链表有头指针,而栈顶指针也是必须的,因此把栈顶放在单链表的头部(头结点->栈顶):相当于头插法;插入新元素e为新的栈顶元素
 */
Status Push(LinkStack *S,SElemType e)
{
    
    
    LinkStackPtr s=(LinkStackPtr) malloc(sizeof(StackNode)); /*声明新结点*/
    s->data = e;
    s->next = S->top;  /*把当前的栈顶元素赋值给新结点的直接后继*/
    S->top = s;  /*将新的结点s赋值给栈顶指针*/
    S->count++;
    return OK;
}
/*出栈操作:用p存储被删除的栈顶结点,将栈顶指针下移一位,最后释放p*/
#include <stdbool.h>
bool StackEmpty(LinkStack S)
{
    
    
    if(S.top ==NULL) /*如果是空栈,则top为*/
        return TRUE;
}
Status Pop(LinkStack *S,SElemType *e)
{
    
    
    LinkStackPtr p;
    if (StackEmpty(*S))
        return ERROR;
    *e = S->top->data;
    p = S->top;
    S->top = S->top->next;
    free(p);
    S->count--;
    return OK;
}

Application de pile

  1. La récursivité, une fonction qui s'appelle directement ou qui s'appelle indirectement via une série d'instructions d'appel est appelée une fonction récursive. Faites attention à la définition de la commande conditionnelle qui ne répond pas à la sortie lorsque l'appel est effectué
    . A. Dans la précédente étape, pour chaque couche de récursion, la fonction Les variables locales, les valeurs des paramètres et les adresses de retour du seront poussées sur la pile.
    b. Dans la phase de retrait, les variables locales, les valeurs de paramètre et l'adresse de retour en haut de la pile sont affichées, utilisées pour revenir au reste du code exécuté dans la hiérarchie des appels et restaurer l'état de l'appel
  2. Les quatre expressions régulières sont évaluées
    a. L'expression entre parenthèses va de gauche à droite, la pile passe de vide à l'élément et devient finalement une pile vide une fois toutes les correspondances réussies
    . B. Expression Postfix et expression infixe (quatre expressions arithmétiques standard ))

file d'attente

Lorsque la longueur maximale de la file d'attente peut être déterminée, il est recommandé d'utiliser une file d'attente circulaire; lorsque la longueur de la file d'attente ne peut pas être estimée, utilisez une file d'attente en chaîne

  1. Table linéaire qui permet uniquement une opération d'insertion à une extrémité et une opération de suppression à l'autre extrémité -> FIFO premier entré premier sorti
  2. La file d'attente est obtenue en fonction de la structure de stockage séquentiel de la table linéaire. Lorsque vous quittez la file d'attente, tous doivent être déplacés. Les éléments de la file d'attente doivent être stockés dans les n premières unités du tableau et les performances de retrait de la file d'attente seront considérablement augmentées. .
  3. Afin d'éviter, lorsqu'il n'y a qu'un seul élément, la tête et la queue de l'équipe se chevauchent et causent des problèmes, utilisez deux pointeurs avant (pointez vers l'élément de tête) et arrière (pointez vers l'élément de queue)
    3.1. Question 1: avant ( pointer vers l'élément head), arrière (Pointant vers l'élément à la fin de la file d'attente), mais cela conduira à la situation où la
    fin de la file d'attente n'a pas de position mais la tête de la file d'attente a une position -> Utilisez le structure de stockage séquentiel de la file d'attente de bout en bout, enregistrée sous forme de file d'attente circulaire
    3.2. Question 2: Pour déterminer si la file d'attente est vide, nous utilisons avant == arrière, mais la condition est également remplie lorsque la file d'attente est pleine
    -> Méthode 1 : Définissez la variable d'indicateur, lorsque l'indicateur = 0, la file d'attente est vide; lorsque l'indicateur = 1, la file d'attente est pleine
    -> Méthode 2: Lorsque la file d'attente est pleine, conservez un élément Espace
    a. Condition de la file d'attente pleine: (arrière + 1 )% QueueSize == avant (l'arrière peut être sur le côté droit de l'avant ou sur le côté gauche de l'avant)
    b. Longueur de la file d'attente: (arrière-avant + QueueSize)

Structure de stockage séquentiel de la file d'attente circulaire

typedef int QElemType; //视情况而定
typedef struct
{
    
    
    QElemType data[MAXSIZE];
    int front; /*头指针*/
    int rear; /*尾指针,若队列不空,指向队列元素的下一个位置*/
}SqQueue;

/*初始化一个空队列*/
Status InitQueue(SqQueue *Q)
{
    
    
    Q->front= 0;
    Q->rear=0;
    return OK;
}
/*返回Q的元素个数,也就是队列的当前长度*/
int QueueLength(SqQueue Q)
{
    
    
    return (Q.rear - Q.front+MAXSIZE)%MAXSIZE;
}
/*循环队列的入队列操作代码*/
Status EnQueue(SqQueue *Q,QElemType e) {
    
    
    if ((Q->rear + 1) % MAXSIZE == Q->front) /*队列满的判断*/
        return ERROR;
    Q->data[Q->rear] = e;  //将元素e赋值给队尾
    Q->rear = (Q->rear + 1) % MAXSIZE; //rear指针向后移一个位置,在末尾则转到数组头部
}

/*循环队列的出队列操作代码*/
Status DeQueue(SqQueue *Q,QElemType *e)
{
    
    
    if (Q->front == Q->rear)
        return ERROR;
    *e= Q->data[Q->front]; //将队头元素赋值给e
    Q->front=(Q->front+1)%MAXSIZE; //front指针向后移一位置,若到最后转到数组头部
}

File d'attente de la chaîne

Liste à lien unique de table linéaire, de fin d'entrée et de sortie, de structure de stockage en chaîne et de réalisation de la file d'attente

typedef int QElemType;
typedef struct QNode
{
    
    
    QElemType data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct  //队列的链表结构
{
    
    
    QueuePtr front,rear; //对头、队尾指针
}LinkQueue;

/*插入元素e为Q的新的队尾元素*/
#include <math.h>
Status EnQueue(LinkQueue *Q,QElemType e)
{
    
    
    QueuePtr  s = (QueuePtr) malloc(sizeof(QNode));
    if (!s)  //存储分配失败
        exit(OVERFLOW);
    s->data=e;
    s->next=NULL;
    Q->rear->next=s; //把拥有yuansue新结点s赋值为原队尾结点的后继
    Q->rear=s; //把当前的s设置为队尾结点,rear指向s
    return OK;
}
Status DeQueue(LinkQueue *Q,QElemType *e)
{
    
    
    QueuePtr p;
    if (Q->front == Q->rear)
        return ERROR;
    p= Q->front->next; //将要删除的队头结点暂存给p
    *e = p->data; // 将要删除的队头结点的值赋值给*e
    Q->front->next = p->next; //将原队头结点后继赋值给头结点后继
    if (Q->rear == p)
        Q->rear = Q->front; //若队头是队尾,则删除后将rear指向头结点(只有头结点和一个元素)
    free(p);
    return OK;
}

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43464554/article/details/113264820
conseillé
Classement