G
N
I
D
A
O
L

【数据结构-栈】栈的基本操作

1 顺序表实现栈

两种实现方式:

  • 栈顶指针 top 指向栈顶元素
  • 栈顶指针 top 指向栈顶元素的下一位置

1.1 定义

# define NUM 50 // 栈的容量

typedef struct Stack{
    int data[NUM];
    int top;
} Stack;

1.2 初始化

  • 栈顶指针 top 指向栈顶元素:
void InitStack (Stack &S){
    S.top = -1;
}
  • 栈顶指针 top 指向栈顶元素的下一位置:
void InitStack (Stack &S){
    S.top = 0;
}

1.3 栈空判断

  • 栈顶指针 top 指向栈顶元素:
bool EmptyStack (Stack &S){
    if (S.top == -1) 
        return true;
    else 
        return false;
}
  • 栈顶指针 top 指向栈顶元素的下一位置:
bool EmptyStack (Stack &S){
    if (S.top == 0) 
        return true;
    else 
        return false;
}

1.4 栈满判断

  • 栈顶指针 top 指向栈顶元素:
bool FullStack (Stack &S){
    if (S.top == NUM-1) 
        return true;
    else 
        return false;
}
  • 栈顶指针 top 指向栈顶元素的下一位置:
bool FullStack (Stack &S){
    if (S.top == NUM) 
        return true;
    else 
        return false;
}

1.5 出栈

  • 栈顶指针 top 指向栈顶元素:
bool PopStack (Stack &S, int &x){
    if (S.top == -1) 
        return false;
    
    x = S.data[S.top];
    S.top--;
    
    return true;
}
  • 栈顶指针 top 指向栈顶元素的下一位置:
bool PopStack (Stack &S, int &x){
    if (S.top == 0) 
        return false;
    
    x = S.data[S.top];
    S.top--;
    
    return true;
}

1.6 入栈

  • 栈顶指针 top 指向栈顶元素:
bool PushStack (Stack &S, const int x){
    if (S.top == NUM-1) 
        return false;
    
    S.top++;
    S.data[S.top] = x;
    
    return true;
}
  • 栈顶指针 top 指向栈顶元素的下一位置:
bool PushStack (Stack &S, const int x){
    if (S.top == NUM) 
        return false;
    
    S.top++;
    S.data[S.top] = x;
    
    return true;
}

1.7 读栈顶元素

  • 栈顶指针 top 指向栈顶元素:
bool GetStackTop (Stack &S, int &x){
    if (S.top == -1) 
        return false;
    
    x = S.data[S.top];
    return true;
}
  • 栈顶指针 top 指向栈顶元素的下一位置:
bool GetStackTop (Stack &S, int &x){
    if (S.top == 0) 
        return false;
    
    x = S.data[S.top-1];
    return true;
}

2 单向链表实现栈

实现方法:

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置(相当于带头结点的链表,头结点正好可以用来记录当前栈存储元素的个数

【注】“栈顶元素在链表表尾”较难实现,因为单向链表只有后继结点。

2.1 定义

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
#define NUM 50 // 栈的容量

typedef struct LinkNode{
    int data;
    struct LinkNode *next;
} LinkNode, *LinkStack;
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
#define NUM 50 // 栈的容量

typedef struct LinkNode{
    int data;
    struct LinkNode *next;
} LinkNode, *LinkStack;

int count; // 记录栈内当前元素个数

2.2 初始化

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
bool InitStack (LinkStack &top){
    top = NULL;
    count = 0;
    return true;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
bool InitStack (LinkStack &head){
    head = (LinkNode *) malloc(sizeof(LinkNode));
    if (head == NULL)
        return false;
        
    head->data = 0; // 用来记录当前栈存储元素的个数
    head->next = NULL; // 后继结点为空
    return true;
}

2.3 栈空判断

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
void EmptyStack (LinkStack &top){
    if (top == NULL)
        return true;
    return false;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
void EmptyStack (LinkStack &head){
    if (head->data == 0)
        return true;
    return false;
}

2.4 栈满判断

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:需要借助外部变量 count 实现
void FullStack (LinkStack &head){
    if (count == NUM)
        return true;
    return false;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
void FullStack (LinkStack &head){
    if (head->data == NUM)
        return true;
    return false;
}

2.5 出栈

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
bool PopStack (LinkStack &top, int &x){
    LinkNode *topNext; // 记录栈顶结点(表头结点)的下一个结点

    if (top == NULL)
        return false;
    
    x = top->data;
    topNext = top->next; // 记录栈顶结点(表头结点)的下一个结点
    free(top);
    
    count--; // 栈内元素个数减少
    return true;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
bool PopStack (LinkStack &head, int &x){
    LinkNode *top; // 记录表头结点的下一个结点(即栈顶结点)
    LinkNode *topNext; // 记录栈顶结点的下一个结点

    if (head->data == 0)
        return false;
    
    top = head->next; // 记录表头结点的下一个结点(即栈顶结点)
    topNext = top->next; // 记录栈顶结点的下一个结点
    x = top->data;
    free(top);
    
    head->data--; // 栈内元素个数减少
    head->next = topNext;
    return true;
}

2.6 入栈

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
bool PushStack (LinkStack &top, const int x){
    LinkNode *newTop; // 新结点

    newTop = (LinkNode *) malloc(sizeof(LinkNode));
    newTop->data = x;
    newTop->next = top; // 新结点的后继结点指向当前栈顶结点
    
    count++; // 栈内元素增加
    top = newTop; // 新结点作为新的栈顶结点
    return true;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
bool PushStack (LinkStack &head, const int x){
    LinkNode *top; // 记录表头结点的下一个结点(即栈顶结点)
    LinkNode *newTop; // 新结点

    if (head->data == NUM)
        return false;
    
    top = head->next; // 记录表头结点的下一个结点(即栈顶结点)
    topNext = top->next; // 记录栈顶结点的下一个结点
    
    newTop = (LinkNode *) malloc(sizeof(LinkNode));
    newTop->data = x;
    newTop->next = top; // 新结点的下一个结点为当前栈顶结点
    
    head->data++; // 栈内元素个数增加
    head->next = newTop; // 新结点作为表头结点的后继结点
    return true;
}

2.7 读栈顶元素

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
bool GetStackTop(LinkStack top, int &x){
    if (top == NULL)
        return false;
    
    x = top->data;
    return true;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
bool GetStackTop(LinkStack head, int &x){
    LinkNode *top = head->next;
    
    if (head->data == 0)
        return false;
    
    x = top->data;
    return true;
}

3 双向链表实现栈

实现方法:

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素
  • 栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置(相当于带头结点的链表,头结点正好可以用来记录当前栈存储元素的个数

【注】“栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素的下一位置”没有意义。

3.1 定义

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
  • 栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素:
typedef struct LinkNode{
    int data;
    struct LinkNode *prev;
    struct LinkNode *next;
} LinkNode, *LinkStack;

int count;
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
typedef struct LinkNode{
    int data;
    struct LinkNode *prev;
    struct LinkNode *next;
} LinkNode, *LinkStack;

3.2 初始化

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
bool InitStack (LinkStack &top){
    top = NULL;
    count = 0;
    return true;
}
  • 栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素:
bool InitStack (LinkStack &top){
    top = NULL;
    count = 0;
    return true;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
bool InitStack (LinkStack &head){
    head = (LinkNode *) malloc(sizeof(LinkNode));
    if (head == NULL)
        return false;
        
    head->data = 0; // 用来记录当前栈存储元素的个数
    head->prev = NULL; // 前驱结点为空
    head->next = NULL; // 后继结点为空
    return true;
}

3.3 栈空判断

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
void EmptyStack (LinkStack &top){
    if (top == NULL)
        return true;
    return false;
}
  • 栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素:
void EmptyStack (LinkStack &top){
    if (top == NULL)
        return true;
    return false;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
void EmptyStack (LinkStack &head){
    if (head->data == 0)
        return true;
    return false;
}

3.4 栈满判断

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:需要借助外部变量 count 实现
  • 栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素:需要借助外部变量 count 实现
void FullStack (LinkStack &head){
    if (count == NUM)
        return true;
    return false;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
void FullStack (LinkStack &head){
    if (head->data == NUM)
        return true;
    return false;
}

3.5 出栈

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
bool PopStack (LinkStack &top, int &x){
    LinkNode *topNext; // 记录栈顶结点(表头结点)的下一个结点

    if (top == NULL)
        return false;
    
    x = top->data;
    topNext = top->next; // 记录栈顶结点(表头结点)的下一个结点
    free(top);
    
    count--; // 栈内元素个数减少
    topNext->prev = NULL;
    top = topNext; // 旧栈顶结点(表头结点)的下一个结点成为新的栈顶结点
    return true;
}
  • 栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素:
bool PopStack (LinkStack &top, int &x){
    LinkNode *topPrev; // 记录栈顶结点(表尾结点)的上一个结点

    if (top == NULL)
        return false;
    
    x = top->data;
    topPrev = top->prev; // 记录栈顶结点(表尾结点)的上一个结点
    free(top);
    
    count--; // 栈内元素个数减少
    topPrev->next = NULL;
    top = topNext; // 旧栈顶结点(表尾结点)的上一个结点成为新的栈顶结点
    return true;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
bool PopStack (LinkStack &head, int &x){
    LinkNode *top; // 记录表头结点的下一个结点(即栈顶结点)
    LinkNode *topNext; // 记录栈顶结点的下一个结点

    if (head->data == 0)
        return false;
    
    top = head->next; // 记录表头结点的下一个结点(即栈顶结点)
    topNext = top->next; // 记录栈顶结点的下一个结点
    x = top->data;
    free(top);
    
    head->data--; // 栈内元素个数减少
    head->next = topNext; // 旧栈顶结点(表头结点)的下一个结点成为新的栈顶结点
    topNext->prev = head; // 新栈顶结点的上一个结点为头结点
    return true;
}

3.6 入栈

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
bool PushStack (LinkStack &top, const int x){
    LinkNode *newTop; // 新结点

    newTop = (LinkNode *) malloc(sizeof(LinkNode));
    newTop->data = x;
    newTop->prev = NULL;
    newTop->next = top; // 新结点的后继结点指向当前栈顶结点
    
    count++; // 栈内元素个数增加
    top->prev = newTop; // 当前栈顶结点的前驱结点为新结点
    top = newTop; // 新结点作为新的栈顶结点
    return true;
}
  • 栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素:
bool PushStack (LinkStack &top, const int x){
    LinkNode *newTop; // 新结点

    newTop = (LinkNode *) malloc(sizeof(LinkNode));
    newTop->data = x;
    newTop->prev = top; // 新结点的后继结点指向当前栈顶结点
    newTop->next = NULL;
    
    count++; // 栈内元素个数增加
    top->next = newTop; //当前栈顶结点的后继结点为新结点
    top = newTop; // 新结点作为新的栈顶结点
    return true;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
bool PushStack (LinkStack &head, const int x){
    LinkNode *top; // 记录表头结点的下一个结点(即栈顶结点)
    LinkNode *newTop; // 新结点

    if (head->data == NUM)
        return false;
    
    top = head->next; // 记录表头结点的下一个结点(即栈顶结点)
    
    newTop = (LinkNode *) malloc(sizeof(LinkNode));
    newTop->data = x;
    newTop->prev = head; // 新结点的前驱结点为头结点
    newTop->next = top; // 新结点的后继结点为当前栈顶结点
    
    head->data++; // 栈内元素个数增加
    top->prev = newTop; // 当前栈顶结点的前驱结点指向新结点
    head->next = newTop; // 新结点作为表头结点的后继结点
    return true;
}

3.7 读栈顶元素

  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素:
bool GetStackTop(LinkStack top, int &x){
    if (top == NULL)
        return false;
    
    x = top->data;
    return true;
}
  • 栈顶元素在链表表尾,且栈顶指针 top 指向栈顶元素:
bool GetStackTop(LinkStack top, int &x){
    if (top == NULL)
        return false;
    
    x = top->data;
    return true;
}
  • 栈顶元素在链表表头,且栈顶指针 top 指向栈顶元素的下一位置:
bool GetStackTop(LinkStack head, int &x){
    LinkNode *top = head->next;
    
    if (head->data == 0)
        return false;
    
    x = top->data;
    return true;
}
posted @ 2022-10-25 17:42  漫舞八月(Mount256)  阅读(103)  评论(0编辑  收藏  举报