队列

队列是一种先进先出(FIFO,First-In-First-Out)的线性表,通常用链表或者数组来实现。队列只能在队尾插入元素,只能在队首删除元素。出队方案唯一。

 

由于队列先进先出,在构造它时需要两个变量 head 和 tail 来代表队首和队尾。

在构造函数中,head初始化为0,tail初始化为-1,并给队列分配内存空间。

在析构函数中,释放分配给队列的内存空间。

 

假上溢:当tail到达队列上限后就不能再插入了,此时再插入就意味着溢出。但是tail到达上限之后并不意味着要插入的元素真的无处可放,因为队列前面有可能是空的。

  1. 要解决假上溢问题,我们可以使用循环队列。
  2. 当队尾标记tail到达队列上限后,如果队列内的元素没有达到上限,就跳转到数组的开始位置,也就是0的位置。
  3. 队首标记到达上限也采取相同的处理。这样可以最大化利用内存空间,避免假上溢。
  4. 循环队列里不能单纯通过比较tail和head标记来判断队列是否已满,要通过统计队列元素个数来判断。

实现队列的构造函数和析构函数:

 1 template <typename Type> class Queue {
 2 private:
 3     Type * data;
 4     int head, tail, length, count;
 5 public:
 6     Queue(int length_input) {
 7         data = new Type[length_input];
 8         length = length_input;
 9         head = 0;
10         tail = -1;
11         count = 0;
12     }
13     ~Queue() {
14         delete[] data;
15     }

实现队列的插入函数:

  1. 判断队列是否已满(count是否等于length);
  2. 更新队尾标记,将新插入元素存入队尾。
 1 bool push(Type element) {
 2         if (count >= length) {
 3             return false;
 4         }
 5    // 对tail取模,这样当tail到达length上限时就重新从0开始
 6         tail = (tail + 1) % length;
 7         data[tail] = element;
 8    // count记录队列元素个数,以后用来判断队列是否已满
 9         count ++;
10         return true;
11     }

实现队列的输出函数:

  1. 输出队首标记所在的元素;
  2. 队首标记后移一位;
  3. 若队尾标记和队首标记相等,输出最后一个元素,否则返回步骤 1。
1 void output() {
2         int i = head;
3         do {
4             cout << data[i] << " ";
5             i = (i + 1) % length;
6         } while (i != (tail + 1) % length); // 当head与tail相等时就完成了队列的输出
7         cout << endl;
8     }

输出队列的首位元素:

1 Type front() {
2         return data[head];
3     }
4  

实现队列的出队操作:

1 void pop() {
2         head = (head + 1) % length; 
3         count --;
4     }

判断队列是否为空:

1 bool empty() {
2         return count == 0;
3     }

 

posted @ 2017-09-13 10:33  Xehanort_Hajime  阅读(210)  评论(0)    收藏  举报