算法与数据结构——栈与队列
栈
定义和基本操作
定义
栈(Stack)是只允许在一端进行插入或删除操作的线性表。
栈是一种线性表,但限定了这种线性表只能在某一端进行插入和删除操作。
重要术语
栈顶(Top):线性表中允许进行插入删除的那一端。
栈底(Bottom):是固定的,不运行进行插入和删除的另一端。
空栈:不含任何元素的空表。
特点:后进先出
Last In First Out
基本操作
// 初始化栈。构造一个空栈S,分配内存空间。
InitStack(&S);
// 销毁栈。销魂并释放栈S所占用的内存空间
DestroyStack(&L);
// 进栈
// 若栈未满,则将x加入使之成为新栈顶
Push(&S, x);
// 出栈
// 若栈S非空,则弹出栈顶元素,并用x返回
Pop(&S, &x);
// 读栈顶元素
// 若栈S非空,则返回栈顶元素
GetTop(S, &x);
// 判断是否为空栈
// 若S为空,则返回true,否则返回false
StackEmpty(S);
栈的物理结构
顺序存储结构
顺序栈的定义
采用顺序存储的栈称为顺序栈,他利用一组地址连续的存储单元存放自栈底到栈顶的数据元素。同时,附设一个指针(top)指示当前栈顶元素的位置。
#define MAXSIZE 10
typedef struct {
ElemType data[MAXSIZE];
int top;
}SqStack;
基本操作
进栈
bool Push(SqStack &S, ElemType x) {
if (S.top == MAXSIZE - 1)
return false;
S.data[++S.top] = x;
return true;
}
出栈
bool Pop(SqStack &S, ElemType &x) {
// 如果栈空,则报错
if(S.top == -1)
return false;
x = data[S.top--];
return true;
}
读栈顶元素
bool GetTop(SqStack S, ElemType &x) {
if (S.top == -1)
return false;
x = S.data[S.top];
return true;
}
共享栈
利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数组空间,将两个站分别设置在共享空间的两端,两个栈顶向共享空间的中间延申。
0号栈为空条件:top0 = -1
1号栈为空条件:top1 = MAXSIZE
栈满条件:top1 - top0 = 1
链式存储结构
栈的存储类型可以描述为:
typedef struct LinkNode {
ElemType data;
struct LinkNode *next;
}*LiStack;
队列
定义和基本操作
定义
队列(Queue):是只允许在一端进行插入,在另一端删除的线性表。
队列的特点:先进先出
First In First Out(FIFO)
重要术语
队头(Front):允许删除的一端,又称队首
队尾(Rear):允许插入的一端
空队列:不含有任何元素的空表
基本操作
创建 销毁 增删改查
// 初始化队列。构造一个空栈S,分配内存空间。
InitStack(&Q);
// 销毁队列。销魂并释放栈S所占用的内存空间
DestroyStack(&Q);
// 入队
// 若队列未满,则将x加入使之成为新队尾
EnQueue(&Q, x);
// 出队
// 若队列Q非空,删除队头元素,并用x返回
DeQueue(&Q, &x);
// 读队头元素
// 若队列Q非空,则返回队头元素
GetHead(Q, &x);
// 判断是否为空队列
// 若Q为空,则返回true,否则返回false
QueueEmpty(Q);
队列的物理结构
顺序存储结构
顺序存储类型可描述为:
#define MAXSIZE 50
typedef struct {
ElemType data[MAXSIZE];
int front, rear;
}SqQueue;
初始化队列
void InitQueue(SeQueue &Q) {
// 初始化时,队头、队尾指针均指向0
Q.rear = Q.front = 0;
}
判断队列是否为空
bool QueueEmpty() {
return (Q.rear == Q.front)
}
入队
bool EnQueue(SqQueue &Q, ElemType x) {
if((Q.rear + 1) % MAXSIZE == Q.front)
return false;
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MAXSIZE;
return true;
}
队列已满的条件:队尾指针的再下一个位置是队头,即(Q.rear + 1) % MAXSIZE == Q.front
链式存储结构
双端队列
考点:判断输出序列的合法性
卡特兰数
$$
1/(n+1) * C2n n
$$