循环队列
什么是队列?
队列是一种先进先出(FIFO)的数据结构。
特点是插入操作只能在队尾进行,删除操作只能在队头进行。
循环队列的设计
我们设计的循环队列的容量为5.
牺牲一个单位,去便利我们的判空和判满操作。
front与rear两个变量用于控制。
类的设计
const int QueueSize=5;
class CirQueue
{
private:
/* data */
// int data[QueueSize]; //队列的底层依然为数组
// int front; //队头指针
// int rear; //队尾指针
public:
int data[QueueSize]; //队列的底层依然为数组
int front; //队头指针 假的队头
int rear; //队尾指针
CirQueue();
~CirQueue();
void EnQueue(int x); //进队
int DeQueue(); //出队,令队头元素出队
int GetHead(); //取队头元素 不删除
bool Empty(); //判断队列是否为空
void PrintQueue(); //遍历输出Queue 排队顺序
};
实现
#include"CirQueue.h"
//牺牲最后一个位置 便于判空判满
CirQueue::CirQueue()
{
//初始化空队列
rear=front=QueueSize-1;
}
CirQueue::~CirQueue()
{
cout<<"析构"<<endl;
}
void CirQueue::EnQueue(int x)
{
//先判断队列是否已满
if((rear+1)%QueueSize==front)
{
cout<<"上溢"<<endl;
return;
}
rear=(rear+1)%QueueSize; //队尾指针 在循环下 后移+1
this->data[rear]=x; //在队尾插入元素
}
int CirQueue::DeQueue()
{
//首先要判空
if(rear==front)
{
cout<<"下溢"<<endl;
throw "下溢";
}
front=(front+1)%QueueSize; //队头指针 在循环下 后移+1
return this->data[front]; //返回出队前的队头元素
}
int CirQueue::GetHead()
{
if(rear==front)
{
cout<<"下溢"<<endl;
throw "下溢";
}
return this->data[(front+1)%QueueSize];
}
bool CirQueue::Empty()
{
if(front==rear)
{
return true;
}
else
{
return false;
}
}
void CirQueue::PrintQueue()
{
if(rear==front)
{
cout<<"下溢,空队列"<<endl;
return;
}
cout<<"此时的front和rear"<<endl;
cout<<"front="<<front<<endl;
cout<<"rear="<<rear<<endl;
int i=(front+1)%QueueSize;
while(i<rear+1)
{
cout<<data[i++]<<" ";
}
cout<<endl;
}
注解1:队头、队尾、头
队头应该是什么呢?
队头应该是队列的第一个元素对应的下标
那么我们这里的front是不是真正的队头呢?
我们进行以下测试
#include"CirQueue.h"
int main()
{
cout<<"循环队列"<<endl;
CirQueue c1;
if(c1.Empty())
{
cout<<"c1.front="<<c1.front<<endl;
cout<<"c1.rear="<<c1.rear<<endl;
cout<<"c1为空队列"<<endl;
}
c1.EnQueue(1);
cout<<"c1.front="<<c1.front<<endl;
cout<<"c1.rear="<<c1.rear<<endl;
c1.PrintQueue();
system("pause");
return 0;
}
这里输出的front是4
可是我们的队头索引应该是0啊
为什么呢?
咱可以把front当成是链表中的head头结点,它的存在是为了方便我们进行操作,实际的首元结点应该是它的下一个,
那么表达式应该怎么写呢?
真正的队头索引应该是(front+1)%QueueSize
后续:请某欢自己写一遍遍历队列的函数。
并且给我画个图!
可是我们的队头索引应该是0啊
为什么呢?
咱可以把front当成是链表中的head头结点,它的存在是为了方便我们进行操作,实际的首元结点应该是它的下一个,
那么表达式应该怎么写呢?
真正的队头索引应该是(front+1)%QueueSize
后续:请某欢自己写一遍遍历队列的函数。
并且给我画个图!
我好饿呀,快出来跟我吃饭…