C语言队列实现

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--;//成员个数-1return  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.hqwc.cn/news/157633.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android开发笔记(三)—Activity篇

活动组件Activity 启动和结束生命周期启动模式信息传递Intent显式Intent隐式Intent 向下一个Activity发送数据向上一个Activity返回数据 附加信息利用资源文件配置字符串利用元数据传递配置信息给应用页面注册快捷方式 启动和结束 &#xff08;1&#xff09;从当前页面跳到新页…

【Elasticsearch 未授权访问漏洞复现】

文章目录 一、漏洞描述二、漏洞复现三、修复建议 一、漏洞描述 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的开放源码发布&am…

Learning to Segment Rigid Motions from Two Frames 代码复现

环境配置 https://github.com/gengshan-y/rigidmask 1.拉取代码 git clone https://github.com/gengshan-y/rigidmask.git cd rigidmask2.创建conda环境&#xff0c;修改rigidmask.yml name: rigidmask channels:- pytorch- pytorch3d- conda-forge- defaults dependencies…

什么情况会造成电表不走数?

电表是衡量用电量的重要设备&#xff0c;一旦出现不走数的情况&#xff0c;不仅会影响用户对用电量的准确计算&#xff0c;还可能造成电费纠纷。那么&#xff0c;究竟什么情况下会造成电表不走数呢&#xff1f;接下来&#xff0c;小编来为大家介绍下&#xff0c;一起来看下吧&a…

FPGA时序分析与约束(8)——时序引擎

一、概述 要想进行时序分析和约束&#xff0c;我们需要理解时序引擎究竟是如何进行时序分析的&#xff0c;包括时序引擎如何进行建立分析&#xff08;setup&#xff09;&#xff0c;保持分析(hold)&#xff0c;恢复时间分析(recovery)和移除时间分析(removal)。 二、时序引擎进…

第十三章,枚举与泛型例题

例题1 package 例题;interface SeasonInterface{//四季接口int SPRING 1, SUMMER 2, AUTUMN 3, WINTER 4; }enum SeasonEnum{//四季枚举SPRING,SUMMER,AUTUMN,WINTER }public class 例题1 {//定义方法public static void printSeason1(int season){switch (season) {case …

Java 性能优化之直接使用成员变量 VS 拷贝副本

背景 刷到一个大佬的 CSDN 博客&#xff0c;仔细看了一下性能优化专栏。联想到我们的日常开发工作&#xff0c;由于业务比较简单&#xff0c;很容就忽略性能问题。但是&#xff0c;性能优化的一下常见思路&#xff0c;也早有耳闻。看了一个 Java 性能优化的方法 「减少操作指令…

深度学习中Transformer的简单理解

Transformer 网络结构 Transformer也是由编码器和解码器组成的。 每一层Encoder编码器都由很多层构成的&#xff0c;编码器内又是self-attention和前馈网络构成的。Self-attention是用来做加权平均&#xff0c;前馈网络用来组合。 但是decoder有点不同&#xff0c;多了一层En…

【docker使用Jar自定义镜像:基于windows】

在一个空文件夹中创建Dockerfile 将jar包复制到该路径下 在Dockerfile中添加以下内容 # 指定基础镜像 FROM java:8-alpine# 和java项目的包 COPY ./study_dockerfile-1.0.0.jar /tmp/app.jar# 暴露端口 EXPOSE 8081# 入口&#xff0c;java项目的启动命令 ENTRYPOINT java -jar…

Android 如何在Android studio中快速创建raw和assets文件夹

一 方案 1. 创建raw文件夹 切成project浏览模式——>找到res文件粘贴要放入raw文件夹下的文件。 当然此时raw文件还没有&#xff0c;直接在右侧输入框中出现的路径~\res后面加上\raw即可。 2. 创建assets文件夹 同理在main文件夹下粘贴要放入assets文件夹的文件&#xff0…

nodejs国内镜像及切换版本工具nvm

淘宝 NPM 镜像站&#xff08;http://npm.taobao.org&#xff09;已更换域名&#xff0c;新域名&#xff1a; Web 站点&#xff1a;https://npmmirror.com Registry Endpoint&#xff1a;https://registry.npmmirror.com 详见&#xff1a; 【望周知】淘宝 NPM 镜像换域名了&…

插件_日期_lunar-calendar公历农历转换

现在存在某需求&#xff0c;需要将公历、农历日期进行相互转换&#xff0c;在此借助lunar-calendar插件完成。 下载 [1] 通过npm安装 npm install lunar-calendar[2]通过文件方式引入 <script type"text/javascript" src"lib/LunarCalendar.min.js">…