数据结构之.队列,循环队列,链式队列(一)

本文详细探讨了循环队列的工作原理,包括如何判断队列的空与满,以及如何处理数据覆盖问题。通过实例分析,提出了一种改进的循环队列设计,允许数据循环覆盖,同时讨论了不同场景下选择不同设计方案的原因。
摘要由CSDN通过智能技术生成

队列你真的懂了吗?队列用来干嘛?什么场景用队列有优势?

一、循环队列

颜色说明如下:
在这里插入图片描述
假设有一个空队列,长度为len = 10 fornt对头,rear队尾初始化时,指向0位置。
注意,这里指向可不是指针的意思,就是front = =rear == 0。
在这里插入图片描述
向队列写入1个数据,rear队尾向后移动一个位置,此时,front == 0,rear = rear + 1,也就是 rear == 1。在这里插入图片描述
继续向队列写入9个数据,rear队尾向后移动一个位置,此时,front = 0,rear = 9。如果是传统队列,此时是不能再写入数据了,rear 不能等于10。
在这里插入图片描述
队列里有9个数据,此时为非空,读走5个数据,此时,front == 5,rear == 9, rear - front == 4。如果是顺序队列,再写数据,此时是从5位置写入数据,前面5个就浪费了。
在这里插入图片描述
队列里有4个数据,此时为非空,再写入1个数据,此时,front == 5,rear =rear + 1, rear == 0。如果是传统顺序队列,
rear - front 是 < 0,不可操作的,不允许再写入,但是本文研究设计的循环队列,是可以写入的,如下。
在这里插入图片描述
再继续看下面。继续写入3个数据,红色为队列满之后写入的数据,此时,front== 5不变,rear == 3,没啥问题啊,为啥前人,会发明顺序队列,是因为不可判断队列数据个数吗,rear - front < 0,是不可以判断的,但是,可不可以增加一种判读机制呢,引入一个count,记录数据个数,每次增加一个数,就加1,读走一个数,就减1。上面步骤最开始是写1个数,count == 1,再写入8个数,就是是9个数,再读走5个数,就还剩4个数,再写入一个数,就是5个,最后,下面步骤,写入3个数,就是8个数,下图,红色和绿色都是代表有数据,刚好是8个数。
在这里插入图片描述
再继续分析如下,读走一个数,front队头向后移动一个位置,还剩7个数。
在这里插入图片描述
再继续读走3个数到最后一个位置,此时,还剩4个数,继续读,会怎么样?
在这里插入图片描述
继续读,如下,队头又回到队尾前面了,此时count == 2。front == 0,rear == 3。
在这里插入图片描述
读走最后两个,此时,front == rear == 3,空队列。
在这里插入图片描述
再来分析,和我们最开始的队列,front == rear == 0,有啥区别?也是空对列,好像是 front == rear,,只是位置在0和3,但是都是队头队尾相等,没有数据的空队列。,此时可以根据front == rear来判断空队列下结论吗?
在这里插入图片描述
继续看,如果把队列都写满,此时,front == rear,为满队列,和上面的空队列一样的情况,所以,不能只靠这个条件进行判读,我们可以加入一个判断条件,count
如果count == 0,且front == rear,则为空队列,如果count != 0,front == rear,为满队列。
在这里插入图片描述
到这里结束了?但是有个毛病,满之后,再继续写,会怎么样?如下图,再写入3个数据,原来是10个,加3个,本来是10+ 3 == 13,现在是把10个满队列的数,前面3个覆盖掉,那不是丢失数据了,就算不考虑丢失的问题,此时要去读取数据时,front == 0,读第0个数,现在读出来的是第11个位置数据,也就是第11个位置的数,而不是被覆盖之前的第0个位置数据,这显然不符合先进先出的思想,因为最现在被覆盖后,最新的数据应该是从第3个数据开始的后面一段数据。
在这里插入图片描述
所以,我们要做一个改进,当队列已满时,不再允许写入数据,只有再次为空时,才允许写入数据。
如果我们希望,可以覆盖,真正实现循环,就需要做如下改进,把队头移动到队尾,front == rear,不关心数据丢失的问题,只希望数据是最新的数据。
在这里插入图片描述
如下,验证设计的正确性,读取2个数据,此时front = front + 2,front == 5。完全正确,为了验证安全性,可以写代码
增加长度,和轮询次数,本文没有验证过,只是理论研究。
在这里插入图片描述
**总结;
1、传统的循环队列其实没有实现真正的循环队列,只是队头队尾可以循环移动,此时可以只根据

front == rear 来判断空。
front== ( rear + 1)% len 来判断满队列。

但是本文真正实现了数据循环覆盖,循环队列。列外判断机制加入了count,与别人有所区别。
1、满队列时,如果希望不覆盖前面的数据,防止数据丢失,可以加判断,满队列将不被允许写入,直到不满。
2、满队列时,如果希望,实现循环写入,将可以通过移动队头到队尾,将数据覆盖。
以上设计,各有各的用处场景,不能说哪个好,场景不同,就要选用不同的方式。**

demo代码:

#include"queue_cmd.h"

PT_QUEUE_CMD QUEUE_CMD_Open(SX_S32 depth)
{
   
	PT_QUEUE_CMD handle = (PT_QUEUE_CMD)xine_xmalloc(sizeof(T_QUEUE_CMD));
	if( handle == NULL )
	{
   
		TRACE(DL_ERROR, "DL_ERROR\n");
		return NULL;
	}
	
	if (pthread_mutex_init( &handle->mutex, NULL ) != 0)
	{
   
		TRACE(DL_ERROR, "DL_ERROR\n");
		QUEUE_CMD_Close( handle );
		return NULL;
	}
	
	if( pthread_cond_init(&handle->cond, NULL) != 0 )
	{
   
		TRACE(DL_ERROR, "DL_ERROR\n");
		QUEUE_CMD_Close( handle );
		return NULL;
	}
	
	handle->ptCmd = (PT_NET_Pkt)xine_xmalloc(sizeof(T_NET_Pkt) * depth);
	if( handle->ptCmd == NULL )
	{
   
		TRACE(DL_ERROR, "DL_ERROR\n");
		QUEUE_CMD_Close( handle );
		return NULL;
	}
	
	handle->s32QueueDepth = depth;
	handle->s32IndexR = 0;
	handle->s32IndexW = 0;
	handle->s32Count = 0;
	handle->bAbortRequest = SX_FALSE;
	
	return handle;
}

void QUEUE_CMD_Close( PT_QUEUE_CMD handle )
{
   
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值