循环队列——基础知识很重要

被NVIDA鄙视情理之中的事情,这么简单的基础知识都没掌握,还是静下心好好看书吧。

 

 

基础知识,基础知识,基础知识,细节一定要研究透彻。

 

 

 

循环队列

 

循环队列一般都是用数组来实现的。

为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。

 

 

循环队列边界条件处理:

循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。

  

解决这个问题的方法至少有两种:

  ① 另设一布尔变量以区别队列的空和满;

  ②另一种方式就是数据结构常用的: 队满时:(rear+1)%n=front,n为队列长度(所用数组大小),由于rear,front均为所用空间的指针,循环只是逻辑上的循环,所以需要求余运算。

 

 

 

Q[0...............M-1],M个元素的数组。队列为空时,队头FRONT与队尾REAR相等。每插入一个元素,REAR增1;每删除一个元素,FRONT减1。

作循环队列用时不能将其填满,因为满了的话REAR标志又与队头标志FRONT相等了,与队列为空时的标志一样,冲突了。

所以要牺牲一个元素的空间了。LENGTH最大只能为M-1;队列满时,(REAR+1)%M == FRONT 就可以用作队列满的判断依据。

经过多次的入队和出队操作后队头和队尾元素都是不确定的,只能在队列满时根据队尾的位置推.

#include <cstdlib> #include <iostream> using namespace std; class CircularQueue { public: CircularQueue(int num) { size = num; data = new int[num]; head = data; tail = data; } void push(int element) { *tail = element; increase(tail); } void pop(int &element) { element = *head; increase(head); } bool isEmpty() { return (head == tail); } bool isFull() { return (((tail - data) + 1) % size + data) == head; } private: int *data; int *head; int *tail; int size; void increase(int *&pointer) { pointer = ((pointer - data) + 1) % size + data; } }; int main(int argc, char *argv[]) { CircularQueue queue(10); // queue.push(0); if(true == queue.isEmpty()) cout<<"empty"<<endl; else cout<<"not empty"<<endl; for(int i = 1; i < 10; i++) queue.push(i); if(true == queue.isFull()) cout<<"Full"<<endl; else cout<<"Not full"<<endl; system("PAUSE"); return EXIT_SUCCESS; }

 

 

你可能感兴趣的:(数据结构,System,存储)