栈和队列
一、 栈
1. 定义
栈是一个先进后出(FILO)
的线性表,它要求只在表尾进行删除和插入操作。
- 栈顶(top):栈的表尾;
- 栈底(bottom):栈的表头。
2. 栈的操作
- 进栈
栈的插入操作(Push),也叫做进栈,也称为压栈,入栈。
入栈操作要在栈顶进行,每次向栈中压入一个数据,top指针就要+1,直到栈满为止。
*(s->top) = e;
s->top++;
- 出栈
栈的删除操作(Pop),叫做出栈。
每当从栈内弹出一个数据,栈的当前容量就-1。
*e = *--(s->top);
- 清空栈
s->top = s->base;
- 计算栈的当前容量
s.top — s.base;
3. 栈的存储结构
- 栈的顺序存储结构
以C为例,自定义栈的顺序存储结构:
typedef struct
{
ElemType *base; // 指向栈底的指针
ElemType *top; // 指向栈顶的指针
int stackSize; // 栈的当前可使用最大容量
}sqStack;
- 栈的链式存储结构
栈顶相当于单链表的表头,栈底相当于单链表的表尾。
以C为例,自定义一个栈的链式存储结构。
typedef struct StackNode
{
ElemType data; // 存放栈的数据
struct StackNode *next;
} StackNode, *LinkStackPtr;
typedef struct LinkStack
{
LinkStackPrt top; // top指针
int count; // 栈元素计数器
}
- 进栈
进栈数据e的新结点为p。
p->data = e;
p->next = s->top;
s->top = p;
- 出栈
用p来保存删除的
*e = s->top->data;
p = s->top;
s->top = s->top->next;
二、 队列
1. 定义
只允许在一端进行插入操作,在另一端进行删除操作的线性表。与栈相反,队列是一种先进先出(FIFO)
的线性表。
2. 队列的存储结构
- 队列的链式存储结构
以C为例,自定义一个队列的链式存储结构。
typedef struct QNode
{
ElemType data;
struct QNode *next;
} QNode, *QueuePrt;
typedef struct
{
Queueprt front, rear; // 队头、尾指针
} LinkQueue;
将队头指针指向链队列的头结点,而队尾指针指向终端结点。(头结点不是必要的,不存放数据。)
- 入队列
入队列的操作过程:
p->data = e;
p->next = null;
q->rear->next = p;
q->rear = p;
- 出队列
出队列操作是将队列中的第一个元素移出,队头指针不发生改变,改变头结点的next指针即可。
QueuePtr p = q->front->next;
*e = p->data;
q->front->next = p->next; //插入头节点之后
if(Q->rear = p) //若原队列中只有一个结点,删除后变空,还需修改尾指针
Q->rear = Q->front;
free(p);
- 队列的顺序存储结构
- 进队
先送值到队尾,再将队尾指针+1
q->data[q->rear] = x;
rear ++;
- 出队
先取出队头元素,再将队头指针+1
x = q->data[q->front]
front ++;
顺序队列会导致假溢出:
- 循环队列
以C为例,定义一个循环队列:
#define MaxSize 100
typedef struct
{
ElemType *base;
int front;
int rear;
}
- 入队列
q->base[q->rear] = e;
q->rear = (q->rear + 1) % MaxSize;
- 出队列
*e = q->base[q->front];
q->front = (q->front + 1) % MaxSize;