数据结构——队列的链式存储结构
队列的链式存储是通过链表实现队列的结构,称为“链式队列”。它利用链表的动态性,无需预先分配固定大小的空间,入队、出队操作仅需修改指针,能灵活应对元素数量的变化,也不会出现顺序队列的“假溢出”问题。链式队列通常有“不带队头结点”和“带队头结点”两种形式,下面分别讲解。
1. 不带队头结点的链式队列
不带队头结点的链式队列,直接通过指针标记队头和队尾元素的位置。如图3.8“不带队头结点的链式队列”所示,front
指向队头元素a₁
所在的结点,rear
指向队尾元素aₙ
所在的结点,链表的最后一个结点(队尾结点)的next
指针为∧
(即NULL
)。队空时,front
和rear
都为NULL
(无任何结点)。
(1)结构定义与初始化
用代码定义不带队头结点的链式队列结构:
typedef struct LinkNode {ElemType data; // 数据域,存储队列的元素值struct LinkNode *next; // 指针域,指向下一个结点
} LinkNode;typedef struct {LinkNode *front, *rear; // 队头指针(指向队头结点)和队尾指针
} LinkQueue;
初始化队列(队空时,front
和rear
均为NULL
):
void InitQueue(LinkQueue &Q) {Q.front = Q.rear = NULL;
}
(2)入队操作
入队是在队尾添加新元素,需分“队空”和“队非空”两种情况处理:
- 若队空(
rear == NULL
):新结点既是队头也是队尾,front
和rear
都指向它; - 若队非空:将新结点接在
rear
之后,再将rear
更新为新结点。
代码实现:
bool EnQueue(LinkQueue &Q, ElemType e) {LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode