栈的概念及其结构
栈:一种特殊的线性表其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端成为栈顶,另一端称为栈底。
元素遵循后进先出原则。
压栈:栈的插入称为进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作称为出栈。出数据在栈顶。
栈的实现
栈一般可以用数组或者链表实现,相对而言数组结构更优一些。
栈的实现一般是采用动态内存管理实现的。
准备环节:
- //以顺序表的形式
- typedef int STDataType;
- typedef struct Stack
- {
- STDataType* a;
- int top;//栈顶
- int capacity;//容量
- }Stack;
1.初始化
基本思路:1)断言
2)指针置空
3)栈顶,容量置为0
代码:
- //初始化
- void StackInit(Stack* ps)
- {
- ps->a = NULL;
- ps->capacity = ps->top = 0;
- }
2.入栈
基本思路:1)断言
2)判断顺序表是否需要扩容
3)插入数据
画图:
类似于顺序表的尾插
代码:
- //入栈
- void StackPush(Stack* ps, STDataType x)
- {
- //断言
- assert(ps);
- //判断是否需要扩容
- if (ps->top == ps->capacity)
- {
- int newcapacity = ps->capacity == 0 ? ps->capacity = 4 : ps->capacity * 2;
- STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
- //判断扩容是否成功
- if (tmp == NULL)
- {
- printf("realloc fail\n");
- exit(-1);
- }
- ps->a = tmp;
- ps->capacity = newcapacity;
- }
- //插入数据
- //数组的下标从0开始,top指向的就是栈顶
- ps->a[ps->top] = x;
- ps->top++;
- }
3.出栈
基本思路:类似于顺序表尾删
1)断言
2)将top--,退一位就行
画图:
代码:
- //出栈
- void StackPop(Stack* ps)
- {
- assert(ps);
- //断言栈是否为空
- assert(ps->top > 0);
-
- ps->top--;
- }
4.获取栈顶元素
基本思路:1)断言
2)断言栈是否为空
3)返回ps->a[ps->top-1]
画图:
可见top指向的是栈顶元素的下一位。
代码:
- //获取栈顶元素
- STDataType StackTop(Stack* ps)
- {
- assert(ps);
- //断言栈是否为空
- assert(ps->top);
-
- return ps->a[ps->top-1];
- }
5.检测栈是否为空
为空返回true非空返回false
基本思路:1)断言传递的指针
2)if判断句或者把 ps->top == 0 的结果返回
代码:
- //检测栈是否为空
- bool StackEmpty(Stack* ps)
- {
- assert(ps);
- 非空
- //if (ps->top > 0)
- //{
- // return false;
- //}
- 为空
- //else
- // return true;
- //更优化的写法
- return ps->top == 0;
- }
6.记录栈里数据个数
基本思路:1)断言
2)top指的值正是数据的个数。
画图:
此时栈数据个数为3,top的值为3.
代码:
- int StackSize(Stack* ps)
- {
- assert(ps);
- //返回个数,top指的是栈顶数据的下一位。
- return ps->top;
- }
7.销毁栈
基本思路:1)断言
2)free指针变量
3)容量和栈顶置为0
代码:
- //销毁
- void StackDestroy(Stack* ps)
- {
-
- free(ps->a);
- ps->a = NULL;
- ps->capacity = ps->top = 0;
- }
依靠已知接口打印栈数据
- #include"Stack.h"
-
- void test()
- {
- Stack st;
- StackInit(&st);
- StackPush(&st, 1);
- StackPush(&st, 2);
- StackPush(&st, 3);
- StackPush(&st, 4);
-
- //printf("%d ", StackTop(&st));
-
- while (!StackEmpty(&st))
- {
- printf("%d ", StackTop(&st));
- StackPop(&st);
- }
- printf("\n");
-
- StackDestroy(&st);
- }
- int main()
- {
- test();
- return 0;
- }
头文件:
- #include<stdio.h>
- #include<assert.h>
- #include<stdlib.h>
- #include<stdbool.h>
-
- //以顺序表的形式
- typedef int STDataType;
- typedef struct Stack
- {
- STDataType* a;
- int top;//栈顶
- int capacity;//容量
- }Stack;
-
- //初始化
- void StackInit(Stack* ps);
-
- //销毁
- void StackDestroy(Stack* ps);
-
- //入栈
- void StackPush(Stack* ps,STDataType x);
-
- //出栈
- void StackPop(Stack* ps);
-
- //获取栈顶元素
- STDataType StackTop(Stack* ps);
-
- //检测栈是否为空
- bool StackEmpty(Stack* ps);
-
- //获取栈有多少个数据
- int StackSize(Stack* ps);