【数据结构导论】第三章-栈、队列和数组
笔记目录
栈及其顺序实现和链接实现
栈的概念
栈(Stack)是运算受限的线性表,这种线性表的插入和删除运算限定在表的某一端进行。允许进行插入和删除的一端为栈顶,另一端为栈底。不含任何数据元素的栈称为空栈。处于栈顶位置的数据元素称为栈顶元素。
栈的后进先出特征
栈的修改原则是后进先出(Last In First Out),因此栈又称为后进先出线性表,简称后进先出表。栈的插入和删除运算分别称为进栈和出栈。
栈的基本运算
- 初始化 InitStack(S) 构造一个空栈
- 判栈空 Empty(S) 若为空栈返回 1,否则返回 0
- 进栈 Push(S,x) 将元素 x 插入栈 S 中,使 x 成为 S 的栈顶
- 出栈 Pop(S,) 删除栈顶元素
- 取栈顶 GetTop(S) 返回栈顶元素
栈顶和栈底
允许进行插入和删除的一端为栈顶,另一端为栈底
顺序栈的组织方法及其类 C 语言描述
栈的顺序存储结构是用一组连续的存储单元依次存放栈中的每个元素,并用始端作为栈底。
栈的顺序实现成为顺序栈。
通常用一个一维数组和一个记录栈顶位置的变量来实现栈的顺序存储。
类 C 语言描述:
1 | const int maxsize = 6; //顺序栈的容量 |
顺序栈栈满和栈空的条件
- 判断栈满:标志栈顶位置的变量等于顺序栈的容量-1
if(stk->top == maxsize - 1)
- 判断栈空:标志栈顶位置的变量等于 0
if(stk->top == 0)
链栈的组织方法及其类 C 语言描述
栈的链接实现称为链栈,链栈可以用带头结点的单链表来实现。
类 C 语言描述:
typedef struct node |
链栈为空的条件
头结点next域为NULL
LS->next == NULL
采用顺序存储和链存储实现栈的基本运算的算法
栈的基本运算在顺序栈上的实现算法
- 初始化
int InitStack(SeqStack *stk) |
- 判栈空
1 | int EmptyStack(SeqStack *stk) |
- 进栈
1 | int Push(SeqStack *stk, DataType x) |
- 出栈
1 | int Pop(SeqStack *stk) |
- 取栈顶元素
1 |
|
栈的基本运算在链栈上的实现算法
- 初始化
void initStack(LKStk *LS) |
- 判栈空
1 | int EmptyStack(LKStk *LS) |
- 进栈
1 | void Push(LKStk *LS, DataType x) |
- 出栈
1 | int Pop(LKStk *LS) |
- 取栈顶元素
1 | DataType GetTop(LKStk *LS) |
队列及其顺序实现和链接实现
队列的概念
队列(Queue)是有限个同类型数据元素的线性序列,是一种先进先出(FirstIn First Out)的线性表。
队列的先进先出基本特征
新加入的队列元素加在队列尾端,出队列的数据元素在队列首部被删除。
队列的基本运算
- 队列初始化 InitQueue(Q) : 设置一个空队列 Q;
- 判队列空 Empty(Q) : 若队列 Q 为空,返回 1,否则返回 0
- 入队列 EnQueue(Q,x) : 将数据元素 x 从队列尾端插入队列
- 出队列 OutQueue(Q) : 删除队列首元素
- 取队列首元素 GetHead(Q) : 返回队列首元素的值
循环队列
队列头尾相接的顺序存储结构叫做循环队列。
队列头和队列尾
顺序存储结构类型中有三个域:data、front、rear。
data 为一维数组
front 为指向队列首元素的前一个单元的指针
rear 为指向队列尾元素单元的指针
顺序队列的组织方法及其类 C 语言描述
一个用于存储队列元素的一维数组和两个分别指示队列首和队列尾的变量,个变量分别称为队列首指针和队列尾指针。

1 | const int maxsize = 20; |
顺序队列满和队列空的条件
队列空:SQ.rear为0,SQ.front为0
队列满:SQ.rear为maxsize
循环队列的组织方法
将存储队列元素的一维数组首尾相接,形成一个环状
循环队列的队列满和队列空的条件
队列满:((CQ.rear + 1) % maxsize == CQ.front)成立
队列空:(CQ.rear == CQ.front)成立
链队列的组织方法及其类 C 语言的描述
使用一个带有头结点的单链表来表示队列,称为链队列。头指针指向单链表头结点,单链表的头结点的 next 域指向队列首结点,尾指针指向队列尾点,即单链表的最后一个结点。
1 | typedef struct LinkQueueNode |
链队列为空的条件
LQ.rear == LQ.front 成立
用数组实现循环队列的基本运算
- 队列初始化
void InitQueue(CycQue CQ) |
- 判队列空
1 | int EmptyQueue(CycQue CQ) |
- 入队列
1 | int EnQueue(CycQue CQ, DataType x) |
- 出队列
1 | int OutQueue(CycQue CQ) |
- 取队列首元素
1 | DataType GetHead(CycQue CQ) |
用链表实现队列的基本运算
- 队列初始化
1 | void InitQueue(LkQueue *LQ) |
- 判队列空
1 | int EmptyQueue(LkQueue *LQ) |
- 入队列
1 | void EnQueue(LkQueue *LQ, DataType x) |
- 出队列
1 | int OutQueue(LkQueue *LQ) |
- 取队列首元素
1 | DataType GetHead(LkQueue *LQ) |
数组及其实现
一维、二维数组的逻辑结构及其顺序存储方法
数组可以看成线性表的一种推广。一维数组又称向量,它由一组具有相同类型的数据元素组成,并存储在一组连续的存储单元中。
二维数组看成 n 个列向量组成的线性表,它可以表示成
a’ =(α0,α1,…,αn-1)
二维数组看成 m 个行向量组成的线性表,它可以表示成
a’’ = (β0,β1,…,βm-1)
顺序存储的一维数组、二维数组的地址计算
loc 为某个求坐标的函数,k 为每个元素所占存储单元
一维数组:loc[i] = loc[0] + i * k
二维数组:loc[i,j] = loc[0,0] + (n * i + j) * k
特殊矩阵(三角矩阵、对称矩阵)的概念
对称矩阵:
若一个 n 阶方阵 A 中的元素满足下述条件:
aij = aji;
0< = i;
j <= n - 1;
则 A 称为对称矩阵
三角矩阵:
以主对角线为界的上/下半部分是一个固定的值 c 或零,这样的矩阵叫做上/下三角矩阵。