栈的定义
栈是一种重要的线性结构,可以这样讲,栈是线性表的一种具体形式。
例如,我们浏览网页,点击后退,我们不会直接返回第一个界面,而是上一个页面,这种后进先出的数据结构就是栈,栈应用是非常广泛的。
例如我们Word,Photoshop等的“撤销”功能也是如此。再例如我们C语言的函数,也是利用栈的基本原理实现的。
官方定义:
栈(Stack)是一个后进先出(Last in first out,LIFO)的线性表,它要求只在表尾进行删除和插入操作。
说到底,所谓的栈,其实也就是一个特殊的线性表(顺序表、链表),但是它在操作上有一些特殊的要求和限制:
栈的元素必须“后进先出”。
栈的操作只能在这个线性表的表尾进行。
注:对于栈来说,这个表尾称为栈的栈顶(top),相应的表头称为栈底(bottom)。
因为栈的本质是一个线性表,线性表有两种存储形式,那么栈也有分为栈的顺序存储结构和栈的链式存储结构。
最开始栈中不含有任何数据,叫做空栈,此时栈顶就是栈底。
然后数据从栈顶进入,栈顶栈底分离,整个栈的当前容量变大。
数据出栈时从栈顶弹出,栈顶下移,整个栈的当前容量变小。
我们可以看到栈的结构如下:
typedef struct{//定义一个栈
int*base;//栈底
int*top;//栈顶
int stacksize;//栈的容量
}sqstack;
栈的初始化操作(创建一个栈)
void initstack(sqstack *s)//初始化一个空栈
{
s->base = (int*)malloc(STACK_INIT_SIZE*sizeof(int));//栈底指向内存的开始
if (!s->base)
return;
s->top = s->base;//栈顶和栈底相同时,栈的容量为0
s->stacksize = STACK_INIT_SIZE;//栈的最大容量
}
栈的插入操作
栈的插入操作(Push),叫做进栈,也称为压栈,入栈。类似子弹放入弹夹的动作。
void push(sqstack*s, int item)//元素入栈
{
if (s->top - s->base >= s->stacksize)//当栈满时,重新扩展栈容量
{
s->base = (int*)realloc(s->base, (STACK_INIT_SIZE + STACKINCREMENT)*sizeof(int));
if (!s->base)
return;
s->top = s->base + s->stacksize;//注意要对栈顶指针进行修改
s->stacksize = STACK_INIT_SIZE + STACKINCREMENT;
}
*(s->top) = item;
s->top++;
}
栈的删除操作
栈的删除操作(Pop),叫做出栈,也称为弹栈。如同弹夹中的子弹出夹。
void pop(sqstack*s,int*e)//元素出栈
{
if (s->top == s->base)//如果栈为空,返回
return;
s->top--;//栈顶指针减一,这里一定是先将top指针减一然后再弹出
*e = *(s->top);//将弹出的元素赋值给e指向的指针
}
栈的清空操作
void clearstack(sqstack*s)//清空一个栈
{
s->top = s->base;
}
栈的销毁操作
DestroyStack(sqStack *s){
int i, len;
len = s->stackSize;
for( i=0; i < len; i++ ){
free( s->base );
s->base++;
}
s->base = s->top = NULL;
s->stackSize = 0;
}
计算栈当前长度的操作
int StackLen(sqStack s)
{
return(s.top – s.base);
}
有不理解的代码可以在下方留言,我会尽快回复