队列是一种先进先出的思想。(First In First Out)
关于队列的定义就不叙述了,百度比我讲的详尽的多,在这里说一下用数组实现队列的思想,并附上代码。
我们身边的与队列相关实例很多,火车站排队买票或是买饭是排队,都是队列。因此我们很容易想到,队列是有一个头一个尾的,新来的总是在尾,最先来的总是最先买票或是吃饭,当然,像插队一类的我们不做考虑,相信我们都不会喜欢这些的。
队列的成员的进出我们已经知道了,总是队头出、队尾进,观看我们身边的实例,我们可以看到,排队时,卖饭的阿姨或是卖票的售票员都是不会移动的,移动的都是成员,那么在代码中,我们也需要这样做吗?每出队一位就让剩下的全体成员集体前移一位,未免太累了。因此我们可以很自然的想到,让卖饭阿姨或是售票员来移动,成员们保持不动,已经买到饭或是买到票的成员就直接离开。可是我们又有一个疑问,在空间有限的情况下(即队列长度有限),当卖饭阿姨移动到队尾给最后一个成员打完饭,队列是不是就没有位置了呢?联系实际我们可以很自然的想到,前面的成员离开了,那么前面的位置就空出来了啊,再有成员进入队列就可以去前面的位置啊,只需要让阿姨在回到最前面重新打饭就可以了啊。这就是队列的思想。
将上述思想化为代码就简单多了。
首先,在有五个位置的队列中,当没有成员进入队列时,队头和队尾显然都在第一个位置。
然后,当有成员进入队列时,阿姨还没有开始打饭,队头显然还是在第一个位置,而第一个进入队列后,下一个成员进入队列应该到哪个位置呢?显然是第二个位置,因此,当队列有一个成员时,队尾在第一个成员的后面,也就是说,队尾总是在最后一个成员的后面。
接着,很快队列就满了,五个位置都有了成员,显然不能有成员再进队列了,这时阿姨开始打饭,给第一个成员打完饭,阿姨就走向第二个成员,也就是说,当第一个成员出去后,队头就到了第二个成员,因此,队头总是在队列的第一个成员。
当阿姨给三个人打完饭后,只有第四第五个位置有人了,又有新的成员想进队打饭,这时他们就会自然而然地走向前面的位置,因为他们知道阿姨打完饭后就会回到第一个位置给他们打饭,这是队尾依然是最后一个进队的成员的后面,只不过这个成员的位置编号在队头前面。
同理,阿姨在给第五个位置的成员打完饭就会回到第一个位置给同学打饭。
队列的思想就是这些了,在用数组实现时,有以下几个地方需要注意:
1、队列的长度就是数组的长度
2、没有成员时,队头队尾都指向第一个位置,即下标为0
3、队头始终指向队列中最先进队的成员,队尾始终指向队列中最后进队的成员的后面下一个位置
3、当队头与队尾的下标相同时,队列为空,因此队尾在指向第四个位置即下标为3时,就应该算队满,否则当队头下标为0时,最后一个位置即第五个位置也有成员,此时队尾下标为0,按照上面的思想应该算队列为空,与实际不符。因此队列的实际容量始终为数组容量减一。
4、按照上面的思想,队头和队尾下标表示应该为(当前下标+1)%数组容量,在第一圈为0,1,2,3,4,第二圈时继续自加明显不合适,因为下标因该为0,因此在自加后对数组容量取余
代码如下:
#include<iostream>
using namespace std;
#define MAXSIZE 10
class queue
{
public:
queue();
bool IsFull();
bool IsEmpty();
bool EnQueue(int);
bool DeQueue(int&);
private:
int buf[MAXSIZE];
int rear;
int front;
};
queue::queue()
{
this->rear=0;
this->front=0;
}
bool queue::IsEmpty()
{
if(this->rear==this->front)
return true;
else
return false;
}
bool queue::IsFull()
{
if((this->rear+1)%MAXSIZE==this->front)
return true;
else
return false;
}
bool queue::EnQueue(int data)
{
if(IsFull())
return false;
this->buf[this->rear]=data;
this->rear=(this->rear+1)%MAXSIZE;
return true;
}
bool queue::DeQueue(int& data)
{
if(IsEmpty())
return false;
data=this->buf[this->front];
this->front=(this->front+1)%MAXSIZE;
}
int main()
{
queue q;
int i=0;
while(i<20)
{
if(q.EnQueue(i))
cout<<"success "<<i<<endl;
else
cout<<"fail "<<i<<endl;
i++;
}
while(q.DeQueue(i))
cout<<i<<" ";
cout<<endl;
return 0;
}