循环队列队满和队空的条件都是front==rear,怎么区分这两者之间的差别?
方案一:
分析:该循环数列包含data数组、队头指针front和队中的元素个数count字段。初始时front和count均置为0.队空的条件为count0;队满的条件为countmaxsize。代码如下:
class SqQueueClass2
{
const int MaxSize=5;
private string[] data; //存放队中的元素
private int front; //队头指针
private int count; //队列中元素的个数
public SqQueueClass2() //构造函数,用于队列初始化
{
data=new string [MaxSize];
front=0;
count=0;
}
}
//-----------------基本运算算法-----------------
//判断队列是否为空-
public bool QueueEmpty()
{
return (count==0);
}
//进队列算法
public bool enQueue(string e)
{
int rear;
rear=(front+count)%MaxSize;
if(count==MaxSize) //队满
Return false;
rear=(rear+1)%MaxSize;
data[rear]=e;
count++;
return true;
}
//出队列算法
public bool deQueue()
{
if (count==0)
return false;
front=(front+1)%MaxSize;
e=data[front];
count--;
return true;
}
//求队列中的元素个数
public int GetCount()
{
return count;
}
方案二:
用front和rear分别作为队头和队尾指针,另外用一个标识tag标识队列可能为空(0)或可能满(1),frontrear可以作为队空或队满的条件。Tag初始值置为0,每当入队成功,tag=1,每当出队成功,tag=0。当frontrear&&tag1时,表示在入队操作后front=rear,此时队满,同理,frontrear&&tag==0时则表示队空。
代码如下:
namespace ConsoleApplication
{
class sqQueueClass
{
const int MaxSize = 100;
public string[] data;
public int front, rear;
public int tag = 0;
public sqQueueClass()
{
data = new string[MaxSize];
front = rear = -1;
}
//判断是否为空
public bool QueueEmpty()
{
return (front == rear && tag == 0);
}
//进队算法
public bool enQueue(string e)
{
if (front == rear && tag == 1)
return false;
rear = (rear + 1) % MaxSize;
data[rear] = e;
tag = 1;
return true;
}
//出队算法
public bool deQueue(ref string e)
{
if (front == rear && tag == 0)
return false;
front = (front + 1) % MaxSize;
e = data[front];
tag = 0;
return true;
}
}
}
比较:
方案一判断条件较为简单,但浪费了一个存储空间,且可用一个count变量直接得知队列中元素的个数;方案二能够充分利用存储空间,但在进行出队入队操作时,每次都需要对tag进行重新定义,除此之外,方案二判断条件也较为复杂。
总结:
由于非循环队列的假溢出现象以及为了能够充分地使用数组的存储空间,把数组的前端和后端连接起来形成循环队列。循环队列在实现入队出队操作时,应注意算法实现顺序,入队时先判断是不是队满,出队时先判断是不是队空,然后再进行相应的入队出队操作。