数据结构实验 6 链队的实现

一、实验目的

1. 掌握队列的链式存储及初始化、创建、求长、销毁、入队、出队等基本操作。

2. 使用C/C++写出链式队列。

3. 了解队列相较于顺序表的特殊性,能在不同情况下选择合适的存储方式。

二、实验要求

1.写出链式队列存储及详细算法步骤;

三、实验过程

实验环境:visual studio 2017

实验步骤:

1. 初始化链队Q,定义函数名为Init_LQueue;

2. 创建链队Q,定义函数名为Create_LQueue;

3. 求链队Q的长度(元素个数),定义函数名为Length_LQueue;

4. 打印链队Q,定义函数名为Print_LQueue;

5. 销毁链队Q,定义函数名为Destory_LQueue;

6. 元素入队,定义函数名为Enqueue;

7. 元素出队,定义函数名为Dequeue;

LQueue.h

#define ELEMTYPE int   //定义一个标识符来表示链队数据的类型
#include<stdio.h>      //调用头文件
#include<stdlib.h>     //调用头文件

typedef struct DataNode     //构建结构体变量存储链队数据相关信息
{
	ELEMTYPE data;          //存放元素
	struct DataNode* next;		//后继结点指针
}DataNode,*Queue;   //DataNode为结构体类型别名,Queue为结构体指针

typedef struct QueueNode		//构建结构体变量存储链队结点相关信息
{
	DataNode* front;			//队头指针
	DataNode* rear;				//队尾指针
}QueueNode;						//结构名为QueueData

void Init_LQueue(Queue* Q,QueueNode* P);						//声明初始化函数——Init_LQueue
void Create_LQueue(Queue* Q,QueueNode* P);					//声明创建函数——Create_LQueue
int Length_LQueue(Queue Q);					//声明求长函数——Length_LQueue
void Print_LQueue(Queue Q);						//声明打印函数——Print_LQueue
void Destory_LQueue(Queue* Q,QueueNode* P);					//声明销毁函数——Destory_LQueue
void Enqueue(QueueNode*P, ELEMTYPE e);				//声明入队函数——Enqueue
void Dequeue(Queue* Q, QueueNode*P, ELEMTYPE* e);				//声明出队函数——Dequeue

LQueue.c

#include "LQueue.h"		//调用头文件

void Init_LQueue(Queue* Q,QueueNode* P)		//初始化链队Q
{
	P = (QueueNode*)malloc(sizeof(QueueNode));		//用malloc给P分配一块内存
	(*Q) = (Queue)malloc(sizeof(DataNode));		//用malloc给链队Q分配一块内存
	P->rear = P->front = (*Q)->next = NULL;	//队头指针、队尾指针和头结点的指针域置为空
}

void Create_LQueue(Queue* Q,QueueNode* P)		//创建链队Q
{
	int length;    //定义整型变量length表示链队Q队长
	printf("Please input the length:");    //提示输入队长length
	scanf("%d", &length);    //输入队长length
	P->rear = (*Q);         //队尾指针指向头结点
	for (int n = 1; n <= length; n++)    //向链队Q中添加n个数据
	{
		DataNode* p;    //定义结构体指针类型变量p
		p = (DataNode*)malloc(sizeof(DataNode));    //用malloc给p分配一块内存
		printf("Please input the data:");    //提示输入结点p的数据域
		scanf("%d", &p->data);    //输入结点p的数据域
		p->next = NULL;				//此时p为尾结点,所以p的指针域置为空
		P->rear->next = p;			//原尾结点的指针域指向当前尾结点
		P->rear = p;				//队尾指针指向当前尾结点p
	}
	P->front = (*Q)->next;			//队头指针指向首元结点
}

int Length_LQueue(Queue Q)			//求链队长度
{
	DataNode* p = Q;    //定义结构体指针类型变量p
	int length = 0;		//定义整型变量length计数
	while (p->next != NULL)			//当p的后继结点不为空(即p不是尾结点)时执行循环
	{
		p = p->next;				//p向后挪动,为原来p的后继结点
		length++;					//计数加1
	}
	return length;				//返回链队长度
}

void Print_LQueue(Queue Q)
{
	DataNode* p = Q;    //定义结构体指针类型变量p
	printf("This Queue is:");       //提示打印队列
	while (p->next != NULL)			//当p的后继结点不为空(即p不是尾结点)时执行循环
	{
		p = p->next;				//p向后挪动,为原来p的后继结点
		printf("%d ", p->data);		//打印p的数据域
	}
	printf("\n");					//换行
}

void Destory_LQueue(Queue* Q, QueueNode* P)
{
	DataNode* p = (*Q),*q;    //定义结构体指针类型变量p,q
	while (p->next != NULL)			//当p的后继结点不为空(即p不是尾结点)时执行循环
	{
		q = p;						//q存储当前结点p
		p = p->next;				//p向后挪动,为原来p的后继结点
		free(q);					//释放原来结点p的空间
		q = NULL;					//原来结点p置为空(防止出现悬空指针)
	}
	free(Q);						//释放链队Q的空间
	free(P);						//释放P的空间
	Q = NULL;						//Q置为空
	P = NULL;						//P置为空
}

void Enqueue(QueueNode* P, ELEMTYPE e)			//将元素e入队
{
	DataNode* p;								 //定义结构体指针类型变量p
	p = (DataNode*)malloc(sizeof(DataNode));		//用malloc给p分配一块内存
	p->data = e;							//将元素e赋值给p的数据域
	p->next = NULL;							//p为尾结点,所以指针域为空
	P->rear->next = p;						//将p链接入队列
	P->rear = p;							//更新尾结点
}

void Dequeue(Queue* Q, QueueNode*P, ELEMTYPE* e)				//将首元结点出队
{
	if (Length_LQueue(*Q) == 0)					//判断队列为空
	{
		printf("Dequeue falied.\n");			//提示出队失败
		return;									//退出函数
	}
	else										//队列不为空
	{
		*e = P->front->data;					//取出原首元结点数据域
		(*Q)->next = P->front->next;			//更新首元结点
		P->front = (*Q)->next;					//更新队头指针
	}
}

Test_Init_Create_Print.c

#include "LQueue.h"				//调用头文件

int main(void)					//main()函数
{
	Queue Q;					//定义结构体指针变量Q
	QueueNode P;				//定义结构体变量P
	Init_LQueue(&Q, &P);		//调用Init_LQueue函数将链队Q初始化
	Create_LQueue(&Q, &P);		//调用Create_LQueue函数创建链队Q
	Print_LQueue(Q);			//调用Print_LQueue函数打印链队Q
	return 0;					//返回值
}

Test_Length.c

#include "LQueue.h"				//调用头文件

int main(void)					//main()函数
{
	Queue Q;					//定义结构体指针变量Q
	QueueNode P;				//定义结构体变量P
	Init_LQueue(&Q, &P);		//调用Init_LQueue函数将链队Q初始化
	Create_LQueue(&Q, &P);		//调用Create_LQueue函数创建链队Q
	printf("This queue's length is:%d\n",Length_LQueue(Q));			//调用Length_LQueue函数打印链队Q长度
	return 0;					//返回值
}

Test_Enqueue.c

#include "LQueue.h"				//调用头文件

int main(void)					//main()函数
{
	Queue Q;					//定义结构体指针变量Q
	QueueNode P;				//定义结构体变量P
	Init_LQueue(&Q, &P);		//调用Init_LQueue函数将链队Q初始化
	Create_LQueue(&Q, &P);		//调用Create_LQueue函数创建链队Q
	Print_LQueue(Q);			//调用Print_Lqueue函数打印链队Q
	ELEMTYPE e;     //定义待入队元素e
	printf("The element to be enqueue is:"); //提示输入待入队的元素
	scanf("%d", &e);    //输入待入队的元素
	Enqueue(&P,e);				//调用Enqueue函数将元素e入队
	Print_LQueue(Q);			//调用Print_LQueue函数打印链队Q
	return 0;					//返回值
}

Test_Dequeue.c

#include "LQueue.h"				//调用头文件

int main(void)					//main()函数
{
	Queue Q;					//定义结构体指针变量Q
	QueueNode P;				//定义结构体变量P
	Init_LQueue(&Q, &P);		//调用Init_LQueue函数将链队Q初始化
	Create_LQueue(&Q, &P);		//调用Create_LQueue函数创建链队Q
	Print_LQueue(Q);			//调用Print_LQueue函数打印链队Q
	ELEMTYPE e = 0;     //定义待入队元素e
	Dequeue(&Q, &P, &e);				//调用Enqueue函数将元素e入队
	Print_LQueue(Q);			//调用Print_LQueue函数打印链队Q
	return 0;					//返回值
}

四、实验结果及分析

测试函数

测试用例

运行结果

Init_LQueue Creat_LQueue

Print_LQueue

5

1,2,3,4,5

Please input the length:5

Please input the data:1

Please input the data:2

Please input the data:3

Please input the data:4

Please input the data:5

This queue is:1 2 3 4 5

0

Please input the length:0

This queue is:

Length_LQueue

5

1,2,3,4,5

This queue's length is:5

0

This queue's length is:0

Enqueue

5

1,2,3,4,5

6

The element to be enqueue is:6

This Queue is:1 2 3 4 5 6

Dequeue

5

1,2,3,4,5

This Queue is:2 3 4 5

0

Dequeue falied.

This Queue is:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Binkkkk

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

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

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

打赏作者

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

抵扣说明:

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

余额充值