【数据结构】队列(链队列、循环队列)的存储结构及基本运算(C语言)_用链队列作存储结构,实现队列(元素为整型)的基本运算。链队列的类型定义:-程序员宅基地

技术标签: c语言  数据结构  

1. 队列基本概念

队列(Queue)是一种限定性线性表,它只允许在表的一端插入元素,而在另一端删除元素,具有先进先出的特点。在队列中,允许插入的一端称为队尾(Rear),允许删除的一端称为队头(Front)。
队列有顺序和链式两种常用存储表示。

2. 链队列

链队列采用带头结点的链表结构,并设置一个队头指针 front 和一个队尾指针 rear ,队头指针始终指向头结点,队尾指针指向最后一个元素。空的链队列的队头指针和队尾指针均指向头结点。
链队列的基本操作包括初始化,队列创建,输出,入队,出队等。
链队列

2.1 代码+注释

# include<stdio.h>
# include<malloc.h>
# define TRUE 1
# define FALSE 0

/*链队列*/
/*链队列的存储结构*/
typedef struct Node {
    
	int data;						//数据域
	struct Node* next;				//指针域
}LinkQueueNode;

typedef struct {
    
	LinkQueueNode* front;
	LinkQueueNode* rear;
}LinkQueue;

/*链队列的初始化*/
int InitQueue(LinkQueue* Q) {
    
	Q->front = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
	if (Q->front != NULL) {
    
		Q->rear = Q->front;
		Q->front->next = NULL;
		return TRUE;
	}
	else
		return FALSE;				//溢出
}

/*链队列的创建*/
void CreateQueue(LinkQueue* Q) {
    
	LinkQueueNode* NewNode;
	int c, flag = 1;
	while (flag) {
    
		scanf("%d", &c);
		if (c != 0) {
    
			NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
			NewNode->data = c;
			Q->rear->next = NewNode;	//新结点插入到队尾
			Q->rear = NewNode;			//修改队尾指针
		}
		else {
    
			flag = 0;
			NewNode->next = NULL;
		}
	}
}

/*链队列入队*/
int EnterQueue(LinkQueue* Q, int x) {
    
	/*将数据元素x插入到队列Q中*/
	LinkQueueNode* NewNode;
	NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
	if (NewNode != NULL) {
    
		NewNode->data = x;
		NewNode->next = NULL;
		Q->rear->next = NewNode;	//新结点插入到队尾
		Q->rear = NewNode;			//修改队尾指针
		return TRUE;
	}
	return FALSE;
}

/*链队列出队*/
int DeleteQueue(LinkQueue* Q, int* x) {
    
	/*将队列Q的队头元素出队,并保存到x中*/
	LinkQueueNode* p;
	if (Q->front == Q->rear)		//空队列
		return FALSE;
	p = Q->front->next;				//p指向队头元素
	Q->front->next = p->next;		//队头元素p出队
	if (Q->rear == p)				//若队中只有一个元素p,则p出队后成为空队
		Q->rear = Q->front;
	*x = p->data;
	free(p);
	return TRUE;
}

/*队列输出*/
void Display(LinkQueue* Q) {
    
	if (Q->front == Q->rear)		//空队列
		printf("空队列!\n");
	else {
    
		LinkQueueNode* p;
		p = Q->front->next;			//p指向队头元素
		while (p != NULL) {
    
			printf("%d ", p->data);
			p = p->next;
		}
		printf("\n");
	}
}

int main() {
    
	int x;
	LinkQueue Q;
	InitQueue(&Q);					//初始化

	printf("创建队列(以0结束):");		//创建
	CreateQueue(&Q);
	printf("创建的队列元素为:");
	Display(&Q);

	EnterQueue(&Q, 5);				//入队
	printf("入队后队中元素为:");
	Display(&Q);

	DeleteQueue(&Q, &x);			//出队
	printf("出队元素为:%d\n", x);
	printf("出队后队中元素为:");
	Display(&Q);
	return 0;
}

2.2 运行结果

链队列运行结果

3. 循环队列

循环队列是一种顺序表示的队列,用一组地址连续的存储单元依次存放从队头到队尾的元素。由于队列中队头和队尾的位置是动态变化的,要附设两个指针 front 和 rear ,分别指示队头元素和队尾元素在数组中的位置。初始化队列时,令 front = rear = 0。
循环队列的基本操作包括初始化,队列创建,输出,入队,出队等。
循环队列

3.1 代码+注释

# include<stdio.h>
# include<malloc.h>
# define TRUE 1
# define FALSE 0
# define MAXSIZE 50

/*循环队列*/
/*循环队列的存储结构*/
typedef struct {
    
	int elem[MAXSIZE];
	int front;
	int rear;
}SeqQueue;

/*循环队列初始化*/
void InitQueue(SeqQueue* Q) {
    
	Q->front = Q->rear = 0;
}

/*循环队列的创建*/
void CreateQueue(SeqQueue* Q) {
    
	int c, flag = 1;
	while (flag) {
    
		scanf("%d", &c);
		if (c != 0) {
    
			Q->elem[Q->rear] = c;
			Q->rear++;
		}
		else {
    
			flag = 0;
		}
	}
}

/*循环队列入队*/
int EnterQueue(SeqQueue* Q, int x) {
    
/*将元素x入队*/
	if ((Q->rear + 1) % MAXSIZE == Q->front)	//队列已满
		return FALSE;
	Q->elem[Q->rear] = x;
	Q->rear = (Q->rear + 1) % MAXSIZE;			//重新设置队尾指针
	return TRUE;
}

/*循环队列出队*/
int DeleteQueue(SeqQueue* Q, int* x) {
    
/*将队列Q的队头元素出队,并保存到x中*/
	if (Q->front == Q->rear)					//队列为空
		return FALSE;
	*x = Q->elem[Q->front];
	Q->front = (Q->front + 1) % MAXSIZE;		//重新设置队头指针
	return TRUE;
}

/*循环队列的输出*/
void Display(SeqQueue* Q) {
    
	if (Q->front == Q->rear)					//队列为空
		printf("空队列!\n");
	else {
    
		int i;
		for (i = Q->front; i < Q->rear; i++)
			printf("%d ", Q->elem[i]);
		printf("\n");
	}
}

int main() {
    
	int x;
	SeqQueue Q;
	InitQueue(&Q);					//初始化

	printf("创建队列(以0结束):");	//创建
	CreateQueue(&Q);
	printf("创建的队列元素为:");
	Display(&Q);

	EnterQueue(&Q, 5);				//入队
	printf("入队后队中元素为:");
	Display(&Q);

	DeleteQueue(&Q, &x);			//出队
	printf("出队元素为:%d\n", x);
	printf("出队后队中元素为:");
	Display(&Q);
	return 0;
}

3.2 运行结果

循环队列运行结果
参考:耿国华《数据结构——用C语言描述(第二版)》

更多数据结构内容关注我的《数据结构》专栏https://blog.csdn.net/weixin_51450101/category_11514538.html?spm=1001.2014.3001.5482

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_51450101/article/details/122641604

智能推荐

Couldn't open file /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7-程序员宅基地

文章浏览阅读1.5k次。Couldn’t open file /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7CentOS7安装任何软件,比如yum -y install ansible出现错误信息:Couldn't open file /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7名词解释:EPEL:extra packages for enterprise l..._couldn't open file /etc/pki/rpm-gpg/rpm-gpg-key-epel-7

Windows添加右键在此处打开命令行_右键 在windows终端打开-程序员宅基地

文章浏览阅读1.9k次,点赞2次,收藏2次。一键自动导入设置。将以下内容保存成reg文件,如a.reg,双击该文件自动导入设置。Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\Directory\Background\shell\OpenCMDHere]"ShowBasedOnVelocityId"=dword:00639bc8[HKEY_CLASSES_ROOT\..._右键 在windows终端打开

Mac 如何干净的卸载 VMware Fusion_macbook中vmware fusion怎么卸载-程序员宅基地

文章浏览阅读9.1k次。# 1. 删除根目录下的,需要用管理员权限sudo rm -rf /Applications/VMware\ Fusion.appsudo rm -rf /Library/Application\ Support/VMwaresudo rm -rf /Library/Preferences/VMware\ Fusionsudo rm -rf /Library/Logs/VMware/s..._macbook中vmware fusion怎么卸载

js用递归遍历多维数组_JS数组的遍历上 (含forEach等方法源码)-程序员宅基地

文章浏览阅读3.5k次。forEach()方法用于调用数组的每个元素(循环遍历数组中的每一个元素),并将元素传递给回调函数。它内部的回调函数可以传入三个参数:function(item, index, arr)item为必填参数,表示当前元素index为可选参数,表示当前元素的索引arr同样为可选参数,表示当前元素所属的数组对象(正在遍历的这个数组)。forEach源码实现:Array.prototype.myForEa..._js递归遍历多维数组

android的apk在oppo手机无法安装(安装包没有签名文件)-程序员宅基地

文章浏览阅读2.6k次。在华为手机可以安装,却在oppo手机无法安装,这是怎么回事呢?原来在打包问题上之前仅仅只勾选了第二个,现在把两个都勾上,然后打包安装到oppo手机,完美解决!========================================Talk is cheap, show me the code============================..._oppo安装不了apk文件

什么才是物联网领域最好的开发语言?_micropython和c++执行效率对比-程序员宅基地

文章浏览阅读5k次。采用C/C++语言,运行最快,一般采用厂家提供的底层驱动支持包BSP,所有MCU都支持。最近很多小伙伴找我,说想要一些物联网学习资料,然后我根据自己从业十年经验,熬夜搞了几个通宵,精心整理了一份「物联网入门到高级教程+工具包」,点个关注,全部无偿共享给大家!采用uLISP语言,利用神奇的LISP语言,函数式编程,开发效率高,运行效率也较好。采用microPython语言,软件开发效率可提高5倍以上,但运行效率一般,有时需要优化,容易学习,需要选择microPython支持的MCU。_micropython和c++执行效率对比

随便推点

Python实现cmd命令连续执行_如何写一个一直执行的进程cmd-程序员宅基地

文章浏览阅读4k次,点赞2次,收藏5次。之前是想写一个微信控制程序,通过登录网页微信,可以直接执行命令行代码。也不用ssh登录了,想法很方便。但是现实很残酷,微信登录这块基本没有问题,已经有大佬写好了,但是命令行执行遇到问题了。运行cmd开始时,使用os.popen()执行命令,但是该命令需要手动修改运行目录。此方案被我直接丢弃了。单开进程那么自然想到通过启动进程的方式来实现,Python有对进程的封装subproc..._如何写一个一直执行的进程cmd

计算机网络之Cisco Packet Tracer仿真实验_计算机网络划分子接口仿真-程序员宅基地

文章浏览阅读9.5k次,点赞22次,收藏96次。本文目的是通过在Cisco Packet Tracer(CPT)软件平台上进行网络的规划和配置,熟悉计算机网络的搭建过程并对计算机网络有更加深入的了解。目录(一)Cisco Packet Tracer(CPT)简介(一)Cisco Packet Tracer(CPT)简介CPT借助思科构建的功能强大的网络仿真工具,可以让我们获得真实的体验。通过练习在各种设备上构建简单而复杂的网络,并扩展到路由器和交换机之外,创建可与智能城市,家庭和企业互连的解决方案。思科Packet Tracer..._计算机网络划分子接口仿真

Tensorflow下用自己的数据集对Faster RCNN进行训练和测试(二)-程序员宅基地

文章浏览阅读2.5w次,点赞3次,收藏127次。对于Tensorflow版本的Faster RCNN网络,网上包括github上都有不同的源码版本,本人之前也在进行不同版本的运行测试,可以说是每个版本都有不同的错误,在解决这些错误时可谓道阻且长。而对于用自己的数据集来训练和测试Faster RCNN网络,本人在之前的博客https://blog.csdn.net/hitzijiyingcai/article/details/81808091中已...

jq 穿梭框_jq穿梭框-程序员宅基地

文章浏览阅读1.1k次。#HTML代码&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;head&gt;&am_jq穿梭框

vue-cli的工程如何正确使用Google Analytics?-程序员宅基地

文章浏览阅读590次。前言最方便的方法,莫过于使用vue-analytics:https://github.com/MatteoGabriele/vue-analytics。包是有了,可是真正使用起来会发现Google Analytics(下称GA)可能没检测到或者出现漏统计的问题。本文的主题,就是讨论几个基本的检查点和说明下GA的基本用法,确保GA正常工作。本文分为以下几部分:如何正确地初始化G..._"cli\": { \"analytics\": false,"

Hybrd A*(混合A*)算法_混合a*算法-程序员宅基地

文章浏览阅读1.5w次,点赞34次,收藏282次。Hybrid A*算法是一种图搜索算法,改进于A*算法。与普通的A*算法区别在于,Hybrid A*规划的路径考虑了车辆的运动学约束,即满足了车辆的最大曲率约束。_混合a*算法

推荐文章

热门文章

相关标签