4、栈
1、栈的定义
栈(Stack)是一个后进先出(Last in first out,LIFO)的线性表,它要求只在表尾进行删除和插入操作。
2、栈特点:
(1)栈的元素必须“后进先出”。
(2)栈的操作只能在这个线性表的表尾进行。
(3)注:对于栈来说,这个表尾称为栈的栈顶(top),相应的表头称为栈底(bottom)。
3、栈的插入和删除操作
栈的插入操作(Push),叫做进栈,也称为压栈,入栈。类似子弹放入弹夹的动作。
栈的删除操作(Pop),叫做出栈,也称为弹栈。如同弹夹中的子弹出夹。
4、最开始栈中不含有任何数据,叫做空栈,此时栈顶就是栈底。然后数据从栈顶进入,栈顶栈底分离,整个栈的当前容量变大。数据出栈时从栈顶弹出,栈顶下移,整个栈的当前容量变小。
5、栈的顺序存储结构
typedef struct
{
ElemType *base;//栈底
ElemType *top;//栈顶
int stackSize;//栈大小
}sqStack;
6、创建一个栈
#define STACK_INIT_SIZE 100 initStack(sqStack *s)
{
s->base = (ElemType *)malloc( STACK_INIT_SIZE * sizeof(ElemType) );
if( !s->base )
exit(0);
s->top = s->base; // 最开始,栈顶就是栈底
s->stackSize = STACK_INIT_SIZE;
}
7、入栈操作
入栈操作又叫压栈操作,就是向栈中存放数据。
1 #define STACKINCREMENT 10//空间 2 3 Push(sqStack *s, ElemType e)//*s指向栈顶的指针,e是栈顶结点的数值 4 { 5 if(s->top - s-base >= s->stackSize) 6 { 7 s->base=(ElemType*)realloc(s->base, (s->stackSize+STACKINCRENT) * sizeof(ElemType));//重新调整内存空间 8 9 if(!s->base) 10 exit(0); 11 12 s->top=s-base+s->stackSize;//设置栈顶 13 s->stackSize=s->stackSize + STACKINCREMENT;//设置栈的最大容量 14 } 15 16 *(s->top)=e;//栈顶赋值 17 s->top++;//栈顶上移 18 }
入栈操作要在栈顶进行,每次向栈中压入一个数据,top指针就要+1,知道栈满为止。
1 Pop(sqStack *s, ElemType *e) 2 { 3 if( s->top == s->base ) // 栈已空空是也 4 return; 5 *e = *--(s->top); 6 }
8、清空一个栈
所谓清空一个栈,就是将栈中的元素全部作废,但栈本身物理空间并不发生改变(不是销毁)。
只要将s->top的内容赋值为s->base即可,这样s->base等于s->top,也就表明这个栈是空的了。
1 ClearStack(sqStack *s) 2 { 3 s->top = s->base; 4 }
9、销毁一个栈
销毁一个栈与清空一个栈不同,销毁一个栈是要释放掉该栈所占据的物理内存空间。
1 DestroyStack(sqStack *s) 2 { 3 int i, len; 4 len = s->stackSize; 5 for( i=0; i < len; i++ ){ 6 free( s->base ); 7 s->base++; 8 } 9 s->base = s->top = NULL; 10 s->stackSize = 0; 11 }
10、计算栈的当前容量
(1)计算栈的当前容量也就是计算栈中元素的个数,因此只要返回s.top-s.base即可。
(2)栈的最大容量是指该栈占据内存空间的大小,其值是s.stackSize,它与栈的当前容量不是一个概念哦。
1 int StackLen(sqStack s) 2 { 3 return(s.top – s.base); // 初学者需要重点讲解 4 }