算法与数据结构——栈与队列

定义和基本操作

定义

栈(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
$$

posted @ 2022-06-14 08:00  Gazikel  阅读(37)  评论(0编辑  收藏  举报