本章知识介绍数据结构书上的第三章栈和队列,其中栈的知识重点放在应用上,因为基本操作较简单,而且c语言和c++都有现成的操作栈和队列的stack<>和queue<>。
栈是限定仅在表尾进行插入或删除操作的线性表。表尾端称为栈顶,表头端称为栈底。另外栈是先进后出(LIFO)的线性表。
栈也是数据结构或者笔试考察的基本知识,经常会有选择题或者填空题,例如阿里笔试的选择题13题
1.原选择题第13题:有堆栈S,按照顺序ABCD进栈,则不可能出栈的顺序是哪个选项,这种选择题,只要仔细分析就不会错,但是一定要认真,切勿大意。
2.还有一种填空题,求n个元素的所有不同出栈顺序共有多少种,比如ABCD进栈,一共有多少种出栈顺序,当然你可以自己一个一个枚举,但是有数学公式就是1/(n+1)*C(2n,n)(因为上标和下标的不好画,这里的C代表求组合数,2n是下标,n是上标),可求得答案是1/5*C(8,4)=14,我记得这个好像叫卡特兰数,原来看过离散数学的书里面有,组合数学里面也有,但是都没学过,具体原理或者推导还是看书吧。
我采取的是用顺序存储结构实现的,就是用数组,如果是链式结构,就用上一章介绍的链表,代码基本参考大话数据结构,其中链式结构大话上也有,这里没有列出,也较简单。
这里的基本操作如下:
int initStack(SqStack *);
int push(SqStack *,int );
int pop(SqStack *,int *);
int getTop(SqStack *,int *);
int length(SqStack *);
int empty(SqStack *);
具体实现的代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
struct SqStack{
int data[MAXSIZE];
int top;
};
int initStack(SqStack *s){
s->top=-1;
return 1;
}
int push(SqStack *s,int e){
if(s->top==MAXSIZE-1){
return 0;
}
s->data[++s->top]=e;
return 1;
}
int pop(SqStack *s,int *e){
if(s->top==-1){
return 0;
}
*e=s->data[s->top--];
return 1;
}
int getTop(SqStack *s,int *e){
if(s->top==-1){
return 0;
}
*e=s->data[s->top];
return 1;
}
int length(SqStack *s){
return s->top+1;
}
int empty(SqStack *s){
if(s->top==-1) return 0;
else return 1;
}
int main(){
SqStack s;
int i;
initStack(&s);
for(i=0;i<10;i++) push(&s,i);
int val=-1;
getTop(&s,&val);
printf("当前栈顶元素:%d,栈长:%d\n",val,length(&s));
val=-1;
pop(&s,&val);
printf("出栈的元素是:%d\n",val);
getTop(&s,&val);
printf("当前栈顶元素:%d,栈长:%d\n",val,length(&s));
return 0;
}
大话还介绍了两栈共享空间,适用情况是一个栈在增长,一个栈在缩短,否则都增长栈很快就满了溢出,就是有两个指针top1和top2指向栈1和栈2,栈1的top1初始值是-1,栈2的初始值是n,栈空的条件就是和初始值的判断,考察的重点一般是栈满的条件,我原来一直以为栈满的条件就是top1+top2==n,当然这是错的,这种从top1出发的角度看是对的,但是如果从top2出发看的话,就错的非常明显了,如果top1只有一个元素,那么top1=0,top2有n-1个元素top2=1,此时栈1或者栈2再来一个元素就栈满了,所以条件应该是top1+1==top2。
未完待续: 下一节 栈和队列算法二之栈的应用
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权