1栈的概念
栈和顺序表、链表一样是属于线性表的一种,栈的特性和顺序表及链表有很大的不同,其他两种结构都支持在头部和尾部还有中部的插入、删除和查找,但栈只能在线性表的一端进行插入数据和删除数据等操作。栈对数据的操作遵循==“后入先出”==原则,即先放入栈中的数据拿出来的时候顺序就靠后。这种概念通过画图更有助于理解,如图
数据从表的一段插入到表中,表的另一端不能进行任何操作,这一端称为栈的栈底,而放入数据的一端称为栈顶,插入数据称为压栈,也可以从栈顶不断的拿出数据直至空栈,拿出数据称为出栈。出栈如图示:
就像上面两幅图是,假定有数据元素1,2,3,4.当进栈顺序是1<-2<-3<-4时,那么依次出栈的顺序就是4<-3<-2<-1了。这种数据运行的规律就好像给一个弹夹装子弹一样,弹夹就是栈,子弹是一个个的数据,不断加入到弹夹中,子弹打出来的时候是后装入的先打出来,还比如老师改作业时的场景,先交的作业放在下面,后交的在上面,改作业时是从上面一本本拿出来改,生活中这种“后入先出”的场景还有很多,就不一一列举了。对栈的操作一次压入一个数据,或弹出一个数据,上面元素1,2,3,4,不改变进栈顺序,但可以有多种出栈顺序,出栈可以是2<-1<4-<3这里就是先连续压入1,2,再弹出来,然后压入3,4,再弹出来。
2.栈的代码实现
栈可以在顺序表或链表的基础上改进之后就实现了,因为栈跟这两种线性表相比就是少了好多的功能,栈只需在一端插入数据,删除数据即可。当用顺序表来实现栈时,只要实现顺序表的尾插和尾删这样的功能就行了,而且顺序表有可以随机访问的作用,比用链表来实现时效率要高,这里我用顺序表来实现栈。
先在头文件中定义一下栈的存储结构,显示要存的数据类型,容量和当前元素个数。
typedef int Datatype;
typedef struct STACK
{
Datatype* a;
int top;
int capacity;
}ST;
在test.c文件中创建一个这种结构体类型的变量
ST Sta;
然后在头文件中声明要实现栈操作的各种函数。
void stackinit(ST* plist); //对栈的初始化
void stackdestory(ST* plist); //栈的销毁
void stackpush(ST* plist,Datatype); //压入数据到栈中
void stackblus(ST* plist); //增容函数
Datatype stackpop(ST* plist); //从栈中弹出数据
int stacksize(ST* plist); // 计算栈中的数据元素个数
void stackdelete(ST* plist); //栈的元素删除
bool stackEmpty(ST* plist); //判断栈是否为空
在stack.c源文件中定义头文件中声明的各个函数
#include"stack.h"
void stackinit(ST*plist)
{
plist->a = NULL;
plist->capacity = plist->top = 0;
}
void stackpush(ST* plist,Datatype x)
{
if (plist->top == plist->capacity)
stackblus(plist);
plist->a[plist->top] = x;
plist->top++;
}
void stackblus(ST* plist)
{
int newcapacity = (plist->top == 0) ? 4 : (2 * (plist->top));
Datatype* tem = (Datatype*)realloc(plist->a, newcapacity* sizeof(Datatype));
assert(tem);
plist->a = tem;
plist->capacity = newcapacity;
}
void stackdestory(ST* plist)
{
free(plist->a);
plist->a = NULL;
plist->capacity = plist->top = 0;
}
Datatype stackpop(ST* plist)
{
assert(plist->top); //空栈没有数据可以弹出
Datatype tem = plist->a[plist->top-1];
plist->top--;
return tem;
}
int stacksize(ST* plist)
{
return plist->top;
}
void stackdelete(ST* plist)
{
assert(plist->top); //判断是否还有元素可删
plist->top--;
}
bool stackEmpty(ST* plist)
{
if (plist->top)
return true;
else
return false;
}
最后就可以在test.c中测试栈的各种操作了
void test1()
{
ST Sta;
stackinit(&Sta);
stackpush(&Sta, 1);
stackpush(&Sta, 2);
stackpush(&Sta, 3);
Datatype a = stackpop(&Sta);
printf("%d ", a);
a = stackpop(&Sta);
printf("%d ", a);
a = stackpop(&Sta);
printf("%d ", a);
}
int main()
{
test1();
return 0;
}
结束语
博客刚开始写,写的比较粗糙,不过也是一个不断学习的过程,我会向大佬看齐的,提高自己的表达能力,对知识总结更加到位,大家一起加油。