3.2.3 队列的链式实现
约 40 分钟
3.2.3 链队列:首尾指针各司其职
链队列通常设带头结点的单链表,并同时保存 front 与 rear。front 指向头结点,rear 指向尾结点;空队列时二者都指向头结点。入队在尾部接结点,出队删除头结点后的首数据结点。
int enqueue(LQueue*q,int x){Node*s=malloc(sizeof*s);if(!s)return 0;
s->data=x;s->next=NULL;q->rear->next=s;q->rear=s;return 1;}
int dequeue(LQueue*q,int*x){Node*p=q->front->next;if(!p)return 0;
*x=p->data;q->front->next=p->next;
if(q->rear==p)q->rear=q->front;free(p);return 1;}
删除最后一个数据结点时,必须把 rear 复位到头结点,否则它仍指向已释放内存。这个分支是链队列最常考的边界。
手工推演:H->7 且 rear 指 7。出队后 H.next=NULL,还要令 rear=H。再入 9 时,从 rear 即 H 接上新结点,链恢复正确;若未复位,入队会通过悬空指针写内存。
链队列入队、出队均为 ,没有固定数组的假溢出,但每个结点有指针与分配开销。若不保存尾指针,尾插需遍历到链尾,退化为 。
错解反馈:出队只移动 front 会把头结点一并丢弃并改变约定;删最后结点不更新 rear 产生悬空指针;入队后忘设 s->next=NULL 可能把未初始化地址接入链。
迁移题:空队列连续入 4、5,出队两次后 front/rear 应满足什么?答案两者再次相等并都指头结点。独立验收:对空、单结点、多结点分别画首尾指针,并逐句执行出队。
小纸条
编程:链队列删除唯一数据结点后,为何要令rear=front?
登录 后可看答案
Practice
本课练习
先独立作答再提交;编程题会在隔离沙箱中真实编译、运行并对拍。
本课练习正在补齐,暂不应标记为完成。