栈
1.栈的定义
栈是只允许在一端进行
插入
或删除
的线性表
。
注意栈是个操作受限的线性表
栈顶
:只允许插入或者删除
栈底
:固定的,不允许进行插入或删除的另一端
空栈
:不含任何数据元素的栈
栈又被称为后进先出的线性表,简称为LIOF(last in first out)
其特殊之处在于限制了这个线性表的插入和删除位置,他始终只在当前栈顶进行操作。
栈的插入操作:也叫做进栈,也叫做压栈与入栈。
栈的删除操作:也叫做出栈,有时也被称为弹栈。
数学性质: n
个不同的元素进栈,出栈元素的不同排列的个数为 N=C(2n,n)/(n+1)
。上述公式也是灰常经典的 卡特兰数
,可采用的数学归纳法去证明。
其原理:
卡特兰数的前几项:1,1,2,5,14,42,132,429,1430,4862…
令h(0)=1,h(1)=1,卡特兰数满足递推式:
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + … + h(n-1)h(0) (n>=2)
例如:h(2)=h(0)h(1)+h(1)h(0)=11+11=2
h(3)=h(0)h(2)+h(1)h(1)+h(2)h(0)=12+11+21=5
个人感觉顺序栈这块出题也就在卡特兰数出了其他没啥难度
基本操作
同时栈这个逻辑结构还分为了顺序栈,共享栈和链栈三种实现方式
栈的顺序存储结构及实现:
采用顺序春促结构的栈称之为
顺序栈
,他利用一组地址连续的存储单元存放到自栈底至栈顶的数据元素,同时附设了一个指针指示当前栈顶元素的位置。
栈的ADT定义:
#define MAXISZIE 20
typedef int ElemType;
typedef struct {
//用数组存储顺序栈中元素
ElemType data[MAXISZIE];
int top;//栈顶指针,从0到maxsize-1,-1表空
//也可以时1到maxsize,0表空
}SeqStack,*PSeqStack;
顺序栈的清空:
//清空顺序栈
void Clear(PSeqStack S) {
//检查空指针
if (S == NULL)
return;
S->top = -1;//采取王道书上的设法
memset(S->data, 0, sizeof(ElemType) * MAXISZIE);
}
顺序栈的销毁:
//顺序栈的销毁
void DestoryStack(PSeqStack S) {
//由于时静态的不需要free
Clear(S);
return;
}
顺序栈的初始化:
//顺序栈的初始化
void InitStack(PSeqStack S) {
Clear(S);//清空
}
顺序栈的判满操作:
//判断顺序栈是否已经满了,返回1表示满0表未满
int IsFull(PSeqStack S) {
if (S == NULL)
return 0;
if (S->top == MAXISZIE - 1)
return 1;
return 0;
}
顺序栈的判空:
//抽象出判空方法便于后面使用
int IsEmpty(PSeqStack S) {
if (S == NULL)
return 0;
if (S->top == -1)
return 1;
return 0;
}
顺序栈的入栈(重点):
//元素入栈.0->失败,1->成功后面也是如此
int Push(PSeqStack S, ElemType* e) {
//日常判空操作
if ((S == NULL) || (e == NULL))
return 0;
if (IsFull(S) == 1) {
printf("顺序栈已满,不能插入。");
return 0;
}
//这时侯如果前面条件满足就可以放入元素咯
//首先分析一下栈顶指针要加一,逻辑层面向上指
S->top++;
memcpy(&S->data[S->top], e, sizeof(ElemType));
return 1;
}
顺序栈的出栈(重点):
//出栈
int Pop(PSeqStack S, ElemType* e) {
if ((S == NULL )||( e == NULL)) {
return 0;
}
if (S->top == -1) {
printf("栈为空");
return 0;
}
//接下来就是成功的情况
//删除元素首先就是要让指针-1然后逻辑上清楚
//首先就是要接受一下数据
memcpy(e, &S->data[S->top], sizeof(ElemType));
S->top--;
return 1;
}
得到栈顶元素(重点):
//获取栈顶元素
//其实本质上就是吧栈顶指针指向的值赋值给e
//成功-1失败-0
int GetTop(PSeqStack S, ElemType* e) {
if ((S == NULL) || (e == NULL)) {
return 0;
}
//如果栈为空同样没有元素哦
if (IsEmpty(S) == 1) {
printf("展位空");
return 0;
}
//开找!
memcpy(e, &S->data[S->top], sizeof(ElemType));
return 1;
}
查询顺序栈的长度:
//查找顺序栈的长度
int Length(PSeqStack S) {
if (S == NULL)
return 0;
return S->top + 1;//因为时从-1开始的当然要加1啦
}
顺序栈的打印:
//打印所有的元素
void PrintStack(PSeqStack S) {
if (S == NULL)
return;
//判断一下栈为空也无法打印
if (IsEmpty == 1) {
return;
}
int count;
for (count = 0; count<=S->top; ++count) {
printf("s[%d],value=%d\n", count, S->data[count]);
}
}