题目
假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针,写出相应的入队列和出队列的算法。
分析
本题是链队基本操作的扩展,知道尾指针后,要实现元素入队,则直接用链表的插入操作即可。要实现出队操作,则需要根据尾指针找出头结点和开始结点,然后进行删除。要注意的是,尾指针应始终指向终端结点,并且当删除结点后队列为空时,必须特殊处理。
代码
核心代码:
/* 入队列 */
/* *&rear指的是尾指针;x指的是要插入的元素值 */
void enQueue(CLNode *&rear,int x) {
CLNode *newNode=(CLNode *)malloc(sizeof(CLNode));// 为要入队的结点分配空间
newNode->data=x;// 赋予数据
newNode->next=rear->next;
rear->next=newNode;// 将新结点链入队尾
rear=newNode;// 将尾指针指向新结点
}
/* 出队列 */
/* *&rear指的是尾指针;&x指的是接收出队元素的值 */
int deQueue(CLNode *&rear,int &x) {
CLNode *tempDelNode;// 指的是要出队的结点
if(rear->next==rear) {
return 0;
} else {
tempDelNode=rear->next->next;// 指向开始结点(第一个结点),rear->next指的是头结点
x=tempDelNode->data;// 保存出队元素的数据
rear->next->next=tempDelNode->next; // 将尾指针的下一个结点指向出队结点的下一个结点
if(tempDelNode==rear) { // 如果元素出队后队列为空,需要特殊处理
rear=rear->next;
}
free(tempDelNode);// 释放结点资源
return 1;// 操作成功返回1
}
}
完整代码:
#include <stdio.h>
#include <stdlib.h>
// 声明循环单链表的结构体
struct CLNode {
int data;
struct CLNode *next;
struct CLNode *rear;// 指向队尾结点的尾指针
};
// 创建一个循环单链表 */
/* *&L指的是要创建的单链表;a[]指的是要批量添加的整数数组;n指的是数组长度 */
void createClist(CLNode *&L,int a[],int n) {
CLNode *temp,*node;
// 创建一个带头结点的单链表
L=(CLNode *)malloc(sizeof(CLNode));
L->next=NULL;
L->rear=NULL;
temp=L; // 尾指针
for(int i=0; i<n; i++) { // 循环添加结点
node=(CLNode *)malloc(sizeof(CLNode)); // 新建结点
node->data=a[i]; // 为结点赋数据值
temp->next=node; // 连接上新添加的结点
temp=node; // 将尾指针指向新添加的结点
}
temp->next=L; // 循环单链表的核心代码。将尾指针的下一个结点指向头结点
L->rear=temp;// 设置尾指针
}
// 打印一个循环单链表 */
/* *L指的是要被打印的循环单链表 */
void printList(CLNode *L) {
CLNode *temp;
temp=L->next;
printf("\n");
while(temp!=L) { // 循环的条件是是否等于头指针
printf("%d\t",temp->data);
temp=temp->next;
}
printf("\n");
}
/* 入队列 */
/* *&rear指的是尾指针;x指的是要插入的元素值 */
void enQueue(CLNode *&rear,int x) {
CLNode *newNode=(CLNode *)malloc(sizeof(CLNode));// 为要入队的结点分配空间
newNode->data=x;// 赋予数据
newNode->next=rear->next;
rear->next=newNode;// 将新结点链入队尾
rear=newNode;// 将尾指针指向新结点
}
/* 出队列 */
/* *&rear指的是尾指针;&x指的是接收出队元素的值 */
int deQueue(CLNode *&rear,int &x) {
CLNode *tempDelNode;// 指的是要出队的结点
if(rear->next==rear) {
return 0;
} else {
tempDelNode=rear->next->next;// 指向开始结点(第一个结点),rear->next指的是头结点
x=tempDelNode->data;// 保存出队元素的数据
rear->next->next=tempDelNode->next; // 将尾指针的下一个结点指向出队结点的下一个结点
if(tempDelNode==rear) { // 如果元素出队后队列为空,需要特殊处理
rear=rear->next;
}
free(tempDelNode);// 释放结点资源
return 1;// 操作成功返回1
}
}
int main() {
CLNode *list,*t1,*t2;
/* [0.]创建初始测试循环单链表 */
int a[]= {1,3,5,7,9};
createClist(list,a,5);
/* [1.]打印循环单链表 */
printList(list);
enQueue(list->rear,11);// 将元素11入队
enQueue(list->rear,22);// 将元素22入队
enQueue(list->rear,33);// 将元素33入队
printList(list);// 打印入队后的链表
int x;
deQueue(list->rear,x);// 出队
printf("出队元素:%d",x);
printList(list);// 打印出队后的链表
return 0;
}
运行结果: