本文来源于《数据结构考研复习指导》,仅做笔记记录用。
栈
栈的基本概念
栈
栈(Stack)是只允许在一端进行插入或删除操作的线性表。
栈顶
栈顶(Top)。线性表允许进行插入删除的那一端。
栈底
栈底(Button)。固定的,不允许进行插入和删除的另一端。
空栈
空栈。不含任何元素的空表。
栈的操作特性
栈的操作特性可以明显地概括为后进先出(Last In First Out, LIFO)。
栈的数学性质
n个不同元素进栈,出栈元素不同排列的个数为 1 n + 1 C 2 n n \frac{1}{n+1}C_{2n}^n n+11C2nn。上述公式称为卡特兰(Catalan)数。
栈的基本操作
- InitStack(&S)
初始化一个空栈 - StackEmpty(S)
判断一个栈是否为空,若栈S为空则返回true,否则返回false - Push(&S, x)
进栈,若栈S未满,则将x加入使之成为新栈顶 - Pop(&S, &x)
出栈,若栈S非空,则弹出栈顶元素,并有x返回 - GetTop(S, &x)
读栈顶元素,若栈S非空,则用x返回栈顶元素 - DestroyStack(&S)
销毁栈,并释放栈S占用的存储空间(&表示引用调用)
栈的顺序存储结构
顺序栈
顺序栈的实现
采用顺序存储的栈称为顺序栈,它利用一组连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针(top)指示当前栈顶元素的位置。
存储类型描述
#define MaxSize 50 // 定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize]; // 存放栈中元素
int top; // 栈顶指针
} SqStack;
其中:
- 栈顶指针:S.top,初始设置
S.top = -1
;栈顶元素:S.data[S.top] - 进栈操作:栈不满时,栈顶指针先+1,再送值到栈顶元素
- 出栈操作:栈非空时,先取栈顶元素,再将栈顶指针-1
- 栈空条件:
S.top == -1
- 栈满条件:
S.top == MaxSize-1
- 栈长:
S.top + 1
顺序栈的基本运算
初始化
void InitStack(SqStack &S) {
S.top = -1; // 初始化栈顶指针
}
栈判空
bool StackEmpty(SqStack S) {
if (S.top == -1)
return true; // 栈空
else
return false; // 不空
}
进栈
bool Push(SqStack &S, ElemType x) {
if (S.top == MaxSize - 1) // 栈满,报错
return false;
S.data[++S.top] = x; // 指针先加1,再入栈
return true;
}
出栈
bool Pop(SqStack &S, ElemType &x) {
if (S.top == -1) // 栈空,报错
return false;
x = S.data[S.top--]; // 先出栈,然后指针减1
return true;
}
读栈顶元素
bool GetTop(SqStack S, ElemType &x) {
if (S.top == -1) // 栈空,报错
return false;
x = S.data[S.top]; // x记录栈顶元素
return true;
}
共享栈
利用栈底位置相对不变的特性,可以让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享口空间的两端,两个栈顶向共享空间的中间延伸。
两个栈顶指针都指向栈顶元素,top0=-1时0号栈为空,top1=MaxSize时1号栈为空;仅当两个栈顶指针相邻(top1-top0=1)时,判断栈满。
0号栈进栈时top0先加1再赋值,1号栈进栈时top1先减1再赋值;出栈相反。
栈的链式存储结构
采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高效率,其不存在栈满上溢情况。通常采用单链表实现,并规定所有操作都在单链表的表头进行。这里规定链栈没有头结点,Lhead指向栈顶元素。
存储类型描述
typedef struct Linknode{
ElemType data; // 数据域
struct Linknode *next; // 指针域
} *LiStack; // 栈类型定义
队列
队列的基本概念
队列
队列(Queue)简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,另一端进行删除。
入队(进队)
即向队列中插入元素
出队(离队)
即在队列中删除元素