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--;//成员个数-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);
	}
}
 

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT_阿水

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

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

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

打赏作者

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

抵扣说明:

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

余额充值