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

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;
}
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值