队列的链式表示和实现

队列的链式表示和实现:

编写一个程序实现链队列的各种基本运算,并在此基础上设计一个主程序,完成如下功能:

  1. 初始化并建立链队列
  2. 销毁链队列
  3. 入队
  4. 出队
  5. 遍历链队列
  6. 判断链队列是否为空
  7. 清空链队列
  8. 获取链队列长度
  9. 获取链队列头元素
代码(C语言):
/*链队列的实现及常用操作测试*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
/*链队列的数据结构*/
typedef int QElemType;
typedef struct QNode  //队列节点
{
	QElemType data;
	struct QNode* next;
} QNode, * QueuePtr;
typedef struct
{
	QueuePtr front;  //队头指针
	QueuePtr rear;   //队尾指针
} LinkQueue;

/*函数声明列表*/
int InitQueue(LinkQueue* Q);             //1 初始化链队列
int DestroyQueue(LinkQueue* Q);          //2 销毁链队列
int EnQueue(LinkQueue* Q, QElemType e);  //3 入队
int DeQueue(LinkQueue* Q, QElemType* e); //4 出队
int QueueEmpty(LinkQueue Q);             //5 判断链队列是否为空
void ClearQueue(LinkQueue* Q);           //6 清空链队列
int QueueLength(LinkQueue Q);            //7 获取链队列长度
int GetHead(LinkQueue Q, QElemType* e);  //8 获取队头元素
void QueueTraverse(LinkQueue Q);         //9 遍历并输出链队列

/*主函数*/
int main(void)
{
	int n = 0, k = 0, i = 0;
	QElemType d = 0;
	LinkQueue Q;
	srand((unsigned)time(NULL));
	int status = InitQueue(&Q);/*构造一个空队列*/
	if (status) printf("队列初始化成功!\n");
	else printf("队列初始化失败!\n");
	printf("输入队列初始元素个数:");
	scanf("%d", &n);
	printf("队列初始化成功!\n执行%d次入队操作:\n", n);
	for (i = 0; i < n; i++)
	{
		d = rand() % 90 + 10;
		printf("第%-2d次:元素%d入队\n", i + 1, d);
		EnQueue(&Q, d); //入队
	}
	printf("打印当前队列:");
	QueueTraverse(Q);

	k = QueueLength(Q); //获取队列长度
	printf("\n当前队列长度为:%d\n\n", QueueLength(Q));
	printf("执行%d次出队操作:\n", k / 2);
	for (i = 0; i < k / 2; i++)
	{
		DeQueue(&Q, &d); //出队
		printf("第%-2d次:元素%d出队", i + 1, d);
		printf("\t打印当前队列:");
		QueueTraverse(Q);
	}
	n = GetHead(Q, &d); //获取队头元素,保存到d中
	if (n) printf("\n队头元素的值:%d\n", d);
	printf("执行清空队列操作\n");
	ClearQueue(&Q); //清空队列
	printf("清空队列后:q.front=%p  q.rear=%p  q.front->next=%p\n", Q.front, Q.rear, Q.front->next);
	DestroyQueue(&Q);
	printf("销毁队列后:q.front=%p  q.rear=%p\n", Q.front, Q.rear);
	return 0;
}

/*函数实现部分*/
/*【功能1 初始化链队列】*/
int InitQueue(LinkQueue* Q)
{
	Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
	if (!Q->front) return 0;/*生成头节点失败*/
	Q->front->next = NULL;
	return 1; //初始化成功则返回1
}

/*【功能2 销毁链队列】*/
int DestroyQueue(LinkQueue* Q)
{
	while (Q->front)
	{
		Q->rear = Q->front->next; /*Q->rear指向Q->front的下一个节点*/
		free(Q->front);/*释放Q->front所指节点*/
		Q->front = Q->rear; /*Q->front指向Q->front的下一个节点*/
	}
	return 1;
}

/*【功能3 入队】*/
int EnQueue(LinkQueue* Q, QElemType e)
{
	QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); /*动态生成新节点*/
	if (!p) return 0;  //生成失败则返回0
	p->data = e;       //将e的值赋给新节点
	p->next = NULL;    //新节点的指针为空
	Q->rear->next = p; //原队尾节点的指针域为指向新节点
	Q->rear = p;       //尾指针指向新节点
	return 1;          //入队成功则返回1
}

/*【功能4 出队】*/
int DeQueue(LinkQueue* Q, QElemType* e)
{
	if (Q->front == Q->rear) return 0; //队列为空则返回0
	QueuePtr p = Q->front->next;       //p指向队头节点
	*e = p->data;                      //队头元素赋给e
	Q->front->next = p->next;          //队头节点指向下一个节点
	if (Q->rear == p) Q->rear = Q->front; //如果删除的是队尾节点,则修改队尾指针指向头节点
	free(p);
	return 1; //出队成功则返回1
}

/*【功能5 判断链队列是否为空】*/
int QueueEmpty(LinkQueue Q)
{
	if (Q.front->next == NULL) return 1; //如果队列为空则返回1
	else return 0;
}

/*【功能6 清空链队列】*/
void ClearQueue(LinkQueue* Q)
{
	Q->front->next = NULL;
}

/*【功能7 获取链队列长度】*/
int QueueLength(LinkQueue Q)
{
	int i = 0; //计数器清0
	QueuePtr p = Q.front; //p指向头节点
	while (p != Q.rear)   //如果p所指向的不是尾节点
	{
		i++; //则计数器加1
		p = p->next;
	}
	return i;
}

/*【功能8 获取队头元素】*/
int GetHead(LinkQueue Q, QElemType* e)
{
	QueuePtr p;
	if (Q.front == Q.rear)
		return 0;
	p = Q.front->next; //p指向队头节点
	*e = p->data;      //将队头元素的值赋给e
	return 1;
}

/*遍历并输出队列(队头到队尾)*/
void QueueTraverse(LinkQueue Q)
{
	QueuePtr p = Q.front->next;
	while (p)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}
执行结果:

在这里插入图片描述

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aabyte

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值