前面我们了解到线性表中的顺序表、链表等结构,今天我们探讨新的一种线性表——栈。
那么我们开始栈的探讨之旅吧。
1.栈的基本概念
1.1栈(Stack):
是只允许在一端进行插入或删除的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。
栈顶(Top):线性表允许进行插入删除的那一端。
栈底(Bottom):固定的,不允许进行插入和删除的另一端。
空栈:不含任何元素的空表。
1.2栈的特点:
因为栈只能在栈顶进行操作,所以栈的特点是先进后出(FILO)
2.栈的实现
对栈的实现,有多种实现的方法
1.顺序栈
- 静态顺序栈
#define MAX_SIZE 100
typedef struct StackNods
{
datatype data[MAX_SIZE];
size_t top;
size_t capacity;
}ST;
缺点:存储空间有限,多了浪费空间,少了不够用
- 动态顺序栈
typedef struct StackNods
{
datatype *array;
size_t top;
size_t capacity;
}ST;
2.链栈
typedef struct StackNods
{
datatype data;
struct StackNods* next;
}ST;
缺点:需要浪费空间存储下一个结点的指针(地址)
综合三种结构,我们采用顺序中的动态栈来完成栈的相关操作:
2.1 栈的初始化
在对栈的初始化之前,有两种情况
top初始化为0的情况:
top初始化为-1的情况
我们从top初始化为0探讨栈的相关操作
//栈的初始化
void Stackinit(ST *pt)
{
assert(pt);
pt->array = (datatype*)malloc(sizeof(datatype) * 4);
if (pt->array == NULL)
{
printf("malloc fail\n");
exit(-1);
}
pt->capacity = 4;
pt->top = 0;
}
2.2压栈
//压栈
void StackPush(ST* pt,datatype x)
{
assert(pt);
ST* tmp=NULL;
if (pt->top == pt->capacity)//表示栈满了 -》扩容
{
tmp = (datatype*)realloc(pt->array, pt->capacity * sizeof(datatype) * 2);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
else
{
pt->array = tmp;
pt->capacity*=2;//容量变成两倍
}
}
pt->array[pt->top] = x;
pt->top++;
}
2.3出栈
void StackPop(ST* pt)
{
assert(pt);//栈空了,调用top,直接种植程序报错
assert(pt->top > 0);
pt->top--;
}
2.4取栈顶元素
//取栈顶元素
datatype StackTop(ST* pt)
{
assert(pt);
assert(pt->top > 0);
return pt->array[pt->top - 1];
}
2.5求栈内元素个数
//求栈内元素个数
int StackSize(ST* pt)
{
assert(pt);
return pt->top;
}
2.6判栈空
//判栈空
bool StackEmpty(ST* pt)//用布尔类型判断
{
assert(pt);
return pt->top == 0;
}
2.7栈打印
//打印
void StackPrintf(ST pt)//打印时不需要对站内元素进行修改,所以不需要传指针
{
while (pt.top)
{
printf("%d ", pt.array[pt.top - 1]);
StackPop(&pt);
}
}
2.8栈销毁
//栈销毁
void StackDestory(ST* pt)
{
assert(pt);
free(pt->array);
pt->array = NULL;
pt->capacity = pt->top = 0;
}
完整代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int datatype;
typedef struct StackNods
{
datatype * array;
size_t top;
size_t capacity;
}ST;
//栈的初始化
void Stackinit(ST *pt)
{
assert(pt);
pt->array = (datatype*)malloc(sizeof(datatype) * 4);
if (pt->array == NULL)
{
printf("malloc fail\n");
exit(-1);
}
pt->capacity = 4;
pt->top = 0;
}
//压栈
void StackPush(ST* pt,datatype x)
{
assert(pt);
ST* tmp=NULL;
if (pt->top == pt->capacity)//表示栈满了 -》扩容
{
tmp = (datatype*)realloc(pt->array, pt->capacity * sizeof(datatype) * 2);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
else
{
pt->array = tmp;
pt->capacity*=2;//容量变成两倍
}
}
pt->array[pt->top] = x;
pt->top++;
}
//出栈
void StackPop(ST* pt)
{
assert(pt);
//栈空了,调用Top,直接种植程序报错
assert(pt->top > 0);
pt->top--;
}
//取栈顶元素
datatype StackTop(ST* pt)
{
assert(pt);
assert(pt->top > 0);
return pt->array[pt->top - 1];
}
//求栈内元素个数
int StackSize(ST* pt)
{
assert(pt);
return pt->top;
}
//判栈空
bool StackEmpty(ST* pt)
{
assert(pt);
return pt->top == 0;
}
//
void StackPrintf(ST pt)
{
while (pt.top)
{
printf("%d ", pt.array[pt.top - 1]);
StackPop(&pt);
}
printf("\n");
}
//栈销毁
void StackDestory(ST* pt)
{
assert(pt);
free(pt->array);
pt->array = NULL;
pt->capacity = pt->top = 0;
}
int main()
{
ST pt;
Stackinit(&pt);
StackPush(&pt, 1);
StackPush(&pt, 1);
StackPush(&pt, 2);
StackPush(&pt, 3);
StackPush(&pt, 4);
StackPrintf(pt);
printf("栈内元素个数有%d 个",StackSize(&pt));
StackDestory(&pt);
return 0;
}
以上就是栈的一些基本操作啦,谢谢大家支持!