C语言队列实现

news2024/11/25 20:31:50

1.知识百科

  队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
  队尾(rear):只能从队尾添加元素,一般焦作enQueue,入队
  队头(front):只能从队头移除元素,一般焦作deQueue,出队
  先进先出的原则、First In Fist Out,FIFO(跟栈是反的,栈是后进先出)
  在生活中队列案例也是随处可见。例如火车站排队买票,银行排队办理业务。
在这里插入图片描述

2.C语言队列实现

  队列可以采用数组或者链表方式实现,数组方式实现存在局限性,数据类型单一,空间大小一开始就需要固定,链表方式实现则比较灵活。

2.1 数组方式实现队列

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define QUEUE_COUNT 50 //队列缓冲区大小
//互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//队列结构体信息
struct Queue_Info{
	int buffer[QUEUE_COUNT];
	int queue_end;//下标
};
struct Queue_Info QueueDat;//队列结构体信息
//判断队列是否满
int Queue_JudgeFull()
{
	if(QueueDat.queue_end>=(QUEUE_COUNT-1))return 1;//队列满
	return 0;//队列未满
}
//判断队列是否为空
int Queue_JudgeNull()
{
	if(QueueDat.queue_end==0)return 1;//队列空
	return 0;//队列有数据
}
//初始化队列
void Queud_Init(void)
{
	memset(&QueueDat,0,sizeof(QueueDat));
}
//入队
int Queud_InPut(int dat)
{
	if(Queue_JudgeFull())return 1;//队列满
	QueueDat.buffer[QueueDat.queue_end++]=dat;
	return 0;
}
//出队
int Queue_OutPut(int *dat)
{
	if(Queue_JudgeNull())return 1;//队列空
	*dat=QueueDat.buffer[0];//从队列头取数据
	//将数组中的数据往前移动
	int i;
	QueueDat.queue_end--;
	for(i=0;i<QueueDat.queue_end;i++)
	{
		QueueDat.buffer[i]=QueueDat.buffer[i+1];
	}
	QueueDat.buffer[i]=0;
	return  0;
}
void *pth_work(void *arg)
{
	int temp;
	while(1)
	{
		//子线程中出队操作
		pthread_mutex_lock(&mutex);//上锁
		if(Queue_OutPut(&temp))
		{
			printf("【子线程1】队列空\n");
		}
		else
		{
			printf("【子线程1】出队成功temp=%d\n",temp);
		}
		pthread_mutex_unlock(&mutex);//解锁
		usleep(300000);
	}	
}
void *pth_work2(void *arg)
{
	int temp;
	while(1)
	{
		//子线程中出队操作
		pthread_mutex_lock(&mutex);//上锁
		if(Queue_OutPut(&temp))
		{
			printf("【子线程2】队列空\n");
		}
		else
		{
			printf("【子线程2】出队成功temp=%d\n",temp);
		}
		pthread_mutex_unlock(&mutex);//解锁
		usleep(200000);
	}	
}
int main()
{
	//初始化队列
	Queud_Init();
	pthread_t pthid;
	//创建线程
	pthread_create(&pthid,NULL,pth_work,NULL);
	pthread_detach(pthid);//设置为分离属性
	pthread_create(&pthid,NULL,pth_work2,NULL);
	pthread_detach(pthid);//设置为分离属性
	int cnt=0;
	while(1)
	{
		//主线程中进行入队
		pthread_mutex_lock(&mutex);//上锁
		cnt++;
		if(Queud_InPut(cnt))
		{
			printf("队列满\n");
		}
		else
		{
			printf("【主线程】入队成功\n");
		}
		pthread_mutex_unlock(&mutex);//解锁
		usleep(200000);
	}
}

在这里插入图片描述

2.2 环形队列

  环形队列的一个有用特性是:当一个数据元素被用掉后,其余数据元素不需要移动其存储位置。相反,一个非环形队列(例如一个普通的队列)在用掉一个数据元素后,其余数据元素需要向前搬移。

在这里插入图片描述

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define QUEUE_COUNT 50 //队列缓冲区大小
//互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//队列结构体信息
struct Queue_Info{
	int buffer[QUEUE_COUNT];//缓冲区
	int queue_count;//成员个数
	int queue_in;//存入数据下标
	int queue_out;//取出数据下标
};
struct Queue_Info QueueDat;//队列结构体信息
//判断队列是否满
int Queue_JudgeFull()
{
	if(QueueDat.queue_count>=QUEUE_COUNT)return 1;//队列满
	return 0;//队列未满
}
//判断队列是否为空
int Queue_JudgeNull()
{
	if(QueueDat.queue_count==0)return 1;//队列空
	return 0;//队列有数据
}
//初始化队列
void Queud_Init(void)
{
	memset(&QueueDat,0,sizeof(QueueDat));
}
//入队
int Queud_InPut(int dat)
{
	if(Queue_JudgeFull())return 1;//队列满
	QueueDat.buffer[QueueDat.queue_in]=dat;
	QueueDat.queue_in=(QueueDat.queue_in+1)%QUEUE_COUNT;//保证下标不会超过缓冲区
	QueueDat.queue_count++;//成员个数++
	return 0;
}
//出队
int Queue_OutPut(int *dat)
{
	if(Queue_JudgeNull())return 1;//队列空
	*dat=QueueDat.buffer[QueueDat.queue_out];//从队列中取数据
	QueueDat.queue_out=(QueueDat.queue_out+1)%QUEUE_COUNT;//保证下标不会超过缓冲区
	QueueDat.queue_count--;//成员个数-1
	return  0;
}
void *pth_work(void *arg)
{
	int temp;
	while(1)
	{
		//子线程中出队操作
		pthread_mutex_lock(&mutex);//上锁
		if(Queue_OutPut(&temp))
		{
			printf("【子线程1】队列空\n");
		}
		else
		{
			printf("【子线程1】出队成功temp=%d\n",temp);
		}
		pthread_mutex_unlock(&mutex);//解锁
		usleep(80000);
	}	
}
void *pth_work2(void *arg)
{
	int temp;
	while(1)
	{
		//子线程中出队操作
		pthread_mutex_lock(&mutex);//上锁
		if(Queue_OutPut(&temp))
		{
			printf("【子线程2】队列空\n");
		}
		else
		{
			printf("【子线程2】出队成功temp=%d\n",temp);
		}
		pthread_mutex_unlock(&mutex);//解锁
		usleep(200000);
	}	
}
int main()
{
	//初始化队列
	Queud_Init();
	pthread_t pthid;
	//创建线程
	pthread_create(&pthid,NULL,pth_work,NULL);
	pthread_detach(pthid);//设置为分离属性
	pthread_create(&pthid,NULL,pth_work2,NULL);
	pthread_detach(pthid);//设置为分离属性
	int cnt=0;
	while(1)
	{
		//主线程中进行入队
		pthread_mutex_lock(&mutex);//上锁
		cnt++;
		if(Queud_InPut(cnt))
		{
			printf("队列满\n");
		}
		else
		{
			printf("【主线程】入队成功\n");
		}
		pthread_mutex_unlock(&mutex);//解锁
		usleep(50000);
	}
}

在这里插入图片描述

2.3 链表方式实现队列

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
//互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//结构体信息
struct Queue_Info{
	int data;
	struct Queue_Info *next;
};
struct Queue_Info *Queue_head;//队列结构体
//初始化队列
struct Queue_Info *Queud_Init(struct Queue_Info *Queue_head,int dat)
{
	if(Queue_head==NULL)
	{
		Queue_head=malloc(sizeof(struct Queue_Info));
		Queue_head->next=NULL;
	}
	Queue_head->data=dat;//添加数据内容
	return Queue_head;
}
//销毁队列
struct Queue_Info *Queud_Destroy(struct Queue_Info *Queue_head)
{
	if(Queue_head==NULL)return Queue_head;
	struct Queue_Info *phead=Queue_head;
	struct Queue_Info *temp=phead;
	int count=0;
	while(phead!=NULL)
	{
		temp=phead;
		phead=phead->next;
		free(temp);
		count++;
	}
	printf("销毁的成员个数:%d\n",count);
	return phead;
}
//获取队列中元素个数
int Queud_GetCount(struct Queue_Info *Queue_head)
{
	struct Queue_Info *phead=Queue_head;
	int count=0;
	while(phead!=NULL)
	{
		phead=phead->next;
		count++;
	}
	return count;
}

//入队(从链表尾添加节点)
struct Queue_Info *Queud_InPut(struct Queue_Info *Queue_head,int dat)
{
	struct Queue_Info *phead=Queue_head;
	if(phead==NULL)
	{
		Queue_head=Queud_Init(Queue_head,dat);
		return Queue_head;
	}
	while(phead->next!=NULL)
	{
		phead=phead->next;
	}
	struct Queue_Info *new=malloc(sizeof(struct Queue_Info));//创建节点
	new->next=NULL;
	phead->next=new;
	new->data=dat;//添加节点内容
	return Queue_head;
}
//出队(从链表头删除节点)
struct Queue_Info *Queue_OutPut(struct Queue_Info *Queue_head,int *dat)
{
	struct Queue_Info *phead=Queue_head;
	if(phead==NULL)return (void *)-1;//队列NULL
	//从队列中取数据
	*dat=phead->data;//取数据
	Queue_head=phead->next;
	free(phead);//释放节点
	return  Queue_head;
}
void *pth_work(void *arg)
{
	int temp;
	while(1)
	{
		//子线程中出队操作
		pthread_mutex_lock(&mutex);//上锁
		Queue_head=Queue_OutPut(Queue_head,&temp);
		if(Queue_head==(void *)-1)
		{
			Queue_head=NULL;
			printf("【子线程1】队列空\n");
		}
		else
		{
			printf("【子线程1】出队成功temp=%d\n",temp);
		}
		pthread_mutex_unlock(&mutex);//解锁
		usleep(80000);
	}	
}
void *pth_work2(void *arg)
{
	int temp;
	while(1)
	{
		//子线程中出队操作
		pthread_mutex_lock(&mutex);//上锁
		Queue_head=Queue_OutPut(Queue_head,&temp);
		if(Queue_head==(void *)-1)
		{
			Queue_head=NULL;
			printf("【子线程2】队列空\n");
		}
		else
		{
			printf("【子线程2】出队成功temp=%d\n",temp);
		}
		pthread_mutex_unlock(&mutex);//解锁
		usleep(200000);
	}	
}
void sig_func(int sig)
{
	if(sig==2)//销毁队列
	{
		pthread_mutex_lock(&mutex);//上锁
		printf("成员个数:%d\n",Queud_GetCount(Queue_head));
		Queue_head=Queud_Destroy(Queue_head);
		pthread_mutex_unlock(&mutex);//解锁
	}
}
int main()
{
	signal(SIGINT,sig_func);//捕获CTRL+C信号
	//初始化队列
	int cnt=0;
	Queue_head=Queud_Init(Queue_head,cnt);
	pthread_t pthid;
	//创建线程
	pthread_create(&pthid,NULL,pth_work,NULL);
	pthread_detach(pthid);//设置为分离属性
	pthread_create(&pthid,NULL,pth_work2,NULL);
	pthread_detach(pthid);//设置为分离属性
	
	while(1)
	{
		//主线程中进行入队
		pthread_mutex_lock(&mutex);//上锁
		cnt++;
		Queue_head=Queud_InPut(Queue_head,cnt);
		printf("【主线程】入队成功,count=%d\n",Queud_GetCount(Queue_head));
		pthread_mutex_unlock(&mutex);//解锁
		usleep(50000);
	}
}
 

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1162674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

月入8K, 计算机专业应届女孩转行5G网络优化工程师,她说:这行请慎入

小C说&#xff0c;如果要用两个字描述23年计算机专业的就业心情&#xff0c;那就是“焦虑”&#xff1b;用三个字描述23年计算机专业的就业环境&#xff0c;那就是“卷麻了”。 得益于张雪峰老师的就业推荐计算机专业需求的日益减少&#xff0c;2023年&#xff0c;计算机专业成…

【漏洞复现】74cms任意文件读取

漏洞描述 74CMS 是一款国内用的比较多招聘网站管理系统&#xff08;Job Board CMS&#xff09;&#xff0c;专注于招聘和人力资源领域的网站建设&#xff0c;存在任意文件读取漏洞 免责声明 技术文章仅供参考&#xff0c;任何个人和组织使用网络应当遵守宪法法律&#xff0c…

vue3中使用deck.gl

deck,gl网址&#xff1a;Home | deck.gl 因为deck.gl是国外的技术&#xff0c;国外最流行的框架是react&#xff0c;所以deck.gl有为react提供的地图组件&#xff0c;没有为vue提供&#xff0c;并且还需要翻墙。所以想用vue使用这个还是有一定难度的。 除了用到deck.gl之外还…

使用Serv-U FTP服务器共享文件,实现无公网IP的外网访问

文章目录 1. 前言2. 本地FTP搭建2.1 Serv-U下载和安装2.2 Serv-U共享网页测试2.3 Cpolar下载和安装 3. 本地FTP发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 科技日益发展的今天&#xff0c;移动电子设备似乎成了我们生活的主角&#xff0c;智能…

vue项目打包时按一定的名称规范生成对应的压缩包

在项目部署中经常需要将打包的dist按一定的名称压缩成压缩包&#xff0c;今天记录一下打包时生成压缩包的过程。其中有用到的npm包需要自己安装一下。 js文件放置的目录如下 compress.js内容如下&#xff1a; // compress.jsimport fs from "fs"; import shell fro…

电商价格数据监测接口|淘宝商品价格接口|天猫商品价格接口|京东商品价格接口|拼多多商品价格接口|API接口申请指南

电商价格数据监测接口是一种可以实时监测电商平台上商品价格的接口工具。通过这个接口&#xff0c;可以获取到各个电商平台的商品价格信息&#xff0c;并且可以设置价格监控频率、智能数据绑定、破价提醒机制等功能。 以下是电商价格数据监测接口的一些特点&#xff1a; 商城…

“恒山光量子”首秀!玻色量子联合移动云发表物理1区Top期刊SCPMA论文

2023年5月&#xff0c;北京玻色量子科技有限公司&#xff08;以下简称“玻色量子”&#xff09;联合移动云在我国知名科技期刊平台《中国科学&#xff1a;物理学 力学 天文学》英文版上发表了以“Optical experimental solution for the multiway number partitioning problem …

网络工程师进阶课:华为HCIP认证课程介绍

微思网络HCIP VIP试听课程&#xff1a;DHCP协议原理与配置https://www.bilibili.com/video/BV1cy4y1J7yg/?spm_id_from333.999.0.0 【微|信|公|众|号&#xff1a;厦门微思网络】 【微思网络http://www.xmws.cn&#xff0c;成立于2002年&#xff0c;专业培训21年&#xff0c;思…

获评AI基础软件「领导者」,九章云极DataCanvas公司技术创新能力最强!

近日&#xff0c;弗若斯特沙利文&#xff08;Frost & Sullivan&#xff0c;简称“沙利文”&#xff09;正式发布《中国AI基础软件市场研究报告&#xff08;2023&#xff09;》&#xff0c;公布当下对中国AI基础软件发展创新的最新洞察。九章云极DataCanvas公司获评AI基础软…

@所有人,城市燃气信息化与信息安全建设方法

关键词&#xff1a;城市燃气信息化、智慧燃气建设、城市燃气安全、智慧燃气、智慧燃气平台 近几年&#xff0c;燃气作为一种新兴的燃料迅速普及开来&#xff0c;和燃气有关的企业之间的竞争也不可避免。身处在互联网的时代&#xff0c;企业只有顺应时代的潮流&#xff0c;将城…

zookeeper集群选举机制

Zookeeper选举机制——第一次启动 zookeeper集群三个重要的参数&#xff08;决定选举结果&#xff09; SID &#xff1a; 服务器 ID 。 用来唯一标识一台 ZooKeeper集群中的机器&#xff0c;每台机器不能重 &#xff0c; 和 myid 一致 。 ZXID &#xff1a;事务 ID 。 ZXID 是…

室内外导航一体化技术原理与成品展示

随着人们对出行需求的不断提升&#xff0c;室内外导航一体化技术变得越来越重要。该技术可以帮助用户在建筑物内、外部空间以及城市范围内进行精确导航&#xff0c;提升出行体验。 室内外一体化导航实现技术原理 室内外导航技术主要依赖于定位技术、地图数据以及空间建模等手段…

YOLOV8 NANO手势识别

采用YOLOV8 NANO训练&#xff0c;得到pt模型&#xff0c;然后转换成ONNX模型&#xff0c;OPENCV DNN调用&#xff0c;支持C,PYTHON,ANDROID开发。CPU每帧20MS左右&#xff0c;可以达到实时性 YOLOV8NANO手势识别

保护隐私,打造独特的个人图床——cpolar+Qchan轻量级搭建——“cpolar内网穿透”

文章目录 前言1. Qchan网站搭建1.1 Qchan下载和安装1.2 Qchan网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar云端设置2.2 Cpolar本地设置 3. 公网访问测试总结 前言 图床作为云存储的一项重要应用场景&#xff0c;在大量开发人员的努力下&#xff0c;已经开发出大…

文言一心中将C语言归类为低级语言,这对么?

文言一心中将C语言归类为低级语言&#xff0c;这对么? 以下是文言一心中的回答&#xff1a;C语言属于低级语言。低级语言通常指的是接近于机器语言的编程语言&#xff0c;它们与计算机硬件的交互更加直接&#xff0c;能够更高效地利用计算机资源。最近很多小伙伴找我&#xff…

SSM使用OpenOffice+Adobe acrobat实现Office文件的在线预览

文章迁移自语雀。 也许Java天生不适合处理Office文件吧&#xff0c;POI的使用一堆问题&#xff0c;现在SpringMVCSpringMybatis的web项目想实现在线预览也是问题一大堆。马的,开始时打算使用OpenOfficeSWFToolsFlexPaper的&#xff0c;但是该方案是使用flash的&#xff0c;众所…

葡萄酒是如何从葡萄园到你的酒杯的?

根据定义&#xff0c;我们称葡萄酒的美味花蜜是葡萄酒精发酵的产物。也有果酒&#xff0c;或乡村酒&#xff0c;是由发酵的水果制成的。然而&#xff0c;传统意义上的葡萄酒是由酿酒葡萄制成的。好吧&#xff0c;一切都是在几个步骤中完成的&#xff0c;来自云仓酒庄品牌雷盛红…

【Linux】进程创建

文章目录 进程创建fork函数初识fork函数返回值写时拷贝fork常规用法fork调用失败的原因 进程创建 fork函数初识 在linux中fork函数时非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。 include <unistd.h> …

【EI会议征稿】第三届电子信息工程、大数据与计算机技术国际学术会议(EIBDCT 2024)

第三届电子信息工程、大数据与计算机技术国际学术会议&#xff08;EIBDCT 2024&#xff09; 2024 3rd International Conference on Electronic Information Engineering, Big Data and Computer Technology 第三届电子信息工程、大数据与计算机技术国际学术会议&#xff08;…

PHP版本升级后,PHPExcel导出下载文件失败,白屏或ERR_INVALID_RESPONSE(网页暂时无法连接,或者它已永久性地移动到了新网址)

PHP版本升级后&#xff0c;PHPExcel导出下载文件失败&#xff0c;白屏或ERR_INVALID_RESPONSE&#xff08;网页暂时无法连接&#xff0c;或者它已永久性地移动到了新网址&#xff09; 这里因为PHP版本过高导致PHPExcel下载失败&#xff1b; 解决方法&#xff1a;打开 PHPExce…