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

Posted Mount256

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-栈栈的基本操作相关的知识,希望对你有一定的参考价值。

文章目录

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++;
    x = S.data[S.top];
    
    return true;

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

1.7 读栈顶元素

  • 栈顶指针 top 指向栈顶元素:
bool GetStackTop (Stack &S, int &x)
    if (S.top == 0) 
        return false;
    
    x = S.data[S.top];
    return true;

  • 栈顶指针 top 指向栈顶元素的下一位置:
bool GetStackTop (Stack &S, int &x)
    if (S.top == -1) 
        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)以上是关于数据结构-栈栈的基本操作的主要内容,如果未能解决你的问题,请参考以下文章

数据结构-栈&队列&Deque实现比较

数据结构------------线性表

11.JDK8内存模型本地方法栈虚拟机栈栈帧结构(局部变量表操作数栈方法出口虚拟机栈与本地方法栈的关系寄存器方法区堆(Heap)jvm中的常量池Metaspace(元空间))

数据结构——栈的实现

数据结构学习笔记(栈队列)整理与总结

数据结构学习笔记(栈队列)整理与总结