当前位置:   article > 正文

【C语言/数据结构】栈:从概念到两种存储结构的实现

【C语言/数据结构】栈:从概念到两种存储结构的实现


目录

一、栈的概念

二、栈的两种实现方式

1.顺序表实现栈

2.链表实现栈

三、栈的顺序存储结构及其实现

1.栈的声明

2.栈的初始化

3.栈的销毁

4.栈的压栈

5.栈的弹栈

6.栈的判空

7.返回栈顶元素

8.返回栈的长度

四、栈的链式存储结构及其实现

1.栈的声明

2.栈的初始化

3.栈的销毁

4.栈的压栈

5.栈的弹栈

6.栈的判空

7.返回栈顶元素

8.返回栈的长度


一、栈的概念

  • 栈的定义:栈是一种特殊的线性表;但在概念上又有一些规定,栈只允许在一端进行数据的插入与删除的操作,被称为栈顶,而另一端则被称为栈底
  • 出栈(弹栈):在栈顶进行数据的删除
  • 入栈(压栈):在栈底进行数据的插入      
  • LIFO原则:栈中的数据服从后进先出原则(last in first out)

二、栈的两种实现方式

1.顺序表实现栈

  • 设计思路:将数组下标为0的位置作为栈底,而数组的最大下标(即长度减一)作为栈顶元素可能存在的位置;用top指向栈顶元素下一位置的索引
  • 压栈:栈的压栈操作,即为顺序表的尾插
  • 弹栈:栈的弹栈操作,即为顺序表的尾删
  • 设计优势:避免了数组增加删除数据时候需要移动数据;压栈与弹栈的时间复杂度为O(1)
  • 自身优势:缓冲区的利用率高;用一段连续的物理地址来存储数据
  • 缺点:动态顺序表实现的栈需要扩容,而扩容会导致空间浪费或性能消耗

2.链表实现栈

  • 设计思路:将单链表的尾部作为栈底,将链表的头部作为栈顶;链表的头指针指针栈顶元素的位置
  • 压栈:栈的压栈操作,即为链表的头插
  • 弹栈:栈的弹栈操作,即为链表的头删
  • 设计优势:避免了链表删除数据结点的时候,需要找到该结点的前一个结点;压栈与弹栈的时间复杂度为O(1)
  • 自身优势:没有扩容所带来的空间的浪费与性能的消耗
  • 缺点:缓存利用率不如顺序表高

三、栈的顺序存储结构及其实现

1.栈的声明

  1. #pragma once
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<stdbool.h>
  6. #include<assert.h>
  7. #define STDateType int
  8. typedef struct Stack
  9. {
  10. STDateType* date;
  11. int top;
  12. int capacity;
  13. }ST;
  14. void STInit(ST* st);
  15. void STDestory(ST* st);
  16. void STPush(ST* st, STDateType x);
  17. void STPop(ST* st);
  18. STDateType STTop(ST* st);
  19. bool STEmpty(ST* st);
  20. int STSize(ST* st);

2.栈的初始化

  1. void STInit(ST* st)
  2. {
  3. assert(st);
  4. st->date = NULL;
  5. st->capacity = st->top = 0;
  6. }

3.栈的销毁

  1. void STDestory(ST* st)
  2. {
  3. assert(st);
  4. free(st->date);
  5. st->date = NULL;
  6. st->top = 0;
  7. st->capacity = 0;
  8. }

4.栈的压栈

  1. void STPush(ST* st, STDateType x)
  2. {
  3. assert(st);
  4. if (st->top == st->capacity)
  5. {
  6. size_t newcapacity = (st->capacity == 0 ? 4 : 2 * st->capacity);
  7. STDateType* tmp = (STDateType*)realloc(st->date, sizeof(STDateType) * newcapacity);
  8. if (tmp != NULL)
  9. {
  10. st->date = tmp;
  11. st->capacity = newcapacity;
  12. }
  13. }
  14. st->date[st->top++] = x;
  15. }

5.栈的弹栈

  1. void STPop(ST* st)
  2. {
  3. assert(st);
  4. assert(st->top > 0);
  5. st->top--;
  6. }

6.栈的判空

  1. bool STEmpty(ST* st)
  2. {
  3. assert(st);
  4. return st->top == 0;
  5. }

7.返回栈顶元素

  1. STDateType STTop(ST* st)
  2. {
  3. assert(st);
  4. assert(st->top > 0);
  5. return st->date[st->top - 1];
  6. }

8.返回栈的长度

  1. int STSize(ST* st)
  2. {
  3. assert(st);
  4. return st->top;
  5. }

四、栈的链式存储结构及其实现

1.栈的声明

  1. #pragma once
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<stdbool.h>
  6. #include<assert.h>
  7. typedef int StDateType;
  8. typedef struct StackNode
  9. {
  10. StDateType date;
  11. struct StackNode* next;
  12. }StackNode;
  13. typedef struct Stack
  14. {
  15. StackNode* top;
  16. size_t size;
  17. }Stack;
  18. void StackInit(Stack* st);//初始化
  19. void StackDestory(Stack* st);//销毁
  20. void StackPush(Stack* st, StDateType x);//压栈
  21. void StackPop(Stack* st);//弹栈
  22. StDateType StackTop(Stack* st);//读取栈顶元素
  23. bool StackEmpty(Stack* st);//判空
  24. size_t StackSize(Stack* st);//返回栈的长度

2.栈的初始化

  1. void StackInit(Stack* st)
  2. {
  3. assert(st);
  4. st->top = NULL;
  5. st->size = 0;
  6. }

3.栈的销毁

  1. void StackDestory(Stack* st)
  2. {
  3. assert(st);
  4. while (st->size > 0)
  5. StackPop(st);
  6. }

4.栈的压栈

  1. void StackPush(Stack* st, StDateType x)
  2. {
  3. assert(st);
  4. StackNode* Node = (StackNode*)malloc(sizeof(StackNode));
  5. if (!Node)
  6. {
  7. perror("malloc mistake");
  8. exit(-1);
  9. }
  10. Node->date = x;
  11. Node->next = NULL;
  12. Node->next = st->top;
  13. st->top = Node;
  14. st->size++;
  15. }

5.栈的弹栈

  1. void StackPop(Stack* st)
  2. {
  3. assert(st);
  4. assert(st->top);
  5. StackNode* tmp = st->top;
  6. st->top = st->top->next;
  7. free(tmp);
  8. st->size--;
  9. }

6.栈的判空

  1. bool StackEmpty(Stack* st)
  2. {
  3. assert(st);
  4. return st->top == NULL;
  5. }

7.返回栈顶元素

  1. StDateType StackTop(Stack* st)
  2. {
  3. assert(st);
  4. return st->top->date;
  5. }

8.返回栈的长度

  1. size_t StackSize(Stack* st)
  2. {
  3. assert(st);
  4. assert(st->top);
  5. return st->size;
  6. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/567922
推荐阅读
相关标签
  

闽ICP备14008679号