考研数据结构之队列(3.3)——练习题之假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针,写出相应的入队列和出队列的算法(C表示)

题目

假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针,写出相应的入队列和出队列的算法。

分析

本题是链队基本操作的扩展,知道尾指针后,要实现元素入队,则直接用链表的插入操作即可。要实现出队操作,则需要根据尾指针找出头结点和开始结点,然后进行删除。要注意的是,尾指针应始终指向终端结点,并且当删除结点后队列为空时,必须特殊处理。

代码

核心代码:

/* 入队列 */
/* *&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;
}

运行结果:

  • 31
    点赞
  • 146
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值