队列是什么???
今天我们来谈一谈队列。
队列同样是一种线性表,但其运算受到一定的限制。其限制在于仅允许在队的一段(这里我们把它叫做队尾)进行插入操作,另一端(把它叫做队首)则进行删除操作。
这和现实生活中的排队类似,由于有秩序,整个队列遵循先进先出原则。故又把队列称为先进先出表。
我们首先用数组对其进行模拟。
队列之数组实现:

//数组模拟队列 #include<iostream> #include<cstdlib> # define maxn 10001 using namespace std; int queue[maxn]; int front = -1;//指向队首 int rear = -1;//指向队尾 void add(int temp)//入队操作 { if(rear>=maxn) cout<<"The queue is full!"<<endl; else queue[++rear]=temp; return; } int del()//出队操作 { if(rear==front) return -1; int temp; temp=queue[++front]; queue[front]=-1; return temp; } void display()//显示队中元素(从队首到队尾) { if(rear==front) { cout<<"The queue is empty!"<<endl; return; } int i=front; cout<<"The front is : "<<front<<endl; cout<<"The rear is : "<<rear<<endl; cout<<"The queue is : "; while(i<rear) { cout<<queue[++i]<<" "; } cout<<endl; return; } int main() { int ins; int i,temp; while(1) { cout<<"1.Input a data."<<endl; cout<<"2.Output a data."<<endl; cout<<"3.Exit."<<endl; cin>>ins; switch(ins) { case 1: cout<<"Please input a value: "; cin>>temp; add(temp); cout<<endl; break; case 2: temp=del(); if(temp==-1) cout<<"The queue is empty!"<<endl; else cout<<"The out value is: "<<temp<<endl; break; case 3: return 0; } display(); system("pause"); system("cls"); } return 0; }
在以上代码实现的过程中,我们可以发现,每次出队操作后都会有数组的空间浪费,这会导致队满后仍有大量空间浪费,我们称之为“假溢出”。
解决假溢出的方法是将线型数组拟成环形,将线性队列拟为循环队列,这样便可以避免大量空间浪费。
不过,口头上说有些抽象,让我们看图。
每当队尾达到数组的最大长度时,我们便将下一个待插入的元素的插入位置(即队尾)转移至数组首端,若该位置可插入,则插入成功,否则判断队满。
可以看出:
队空时,rear==front;
队满时,((rear+1)%maxn==front);
队空时的条件应该很好理解,这里我们只说说队满时的条件讨论。
这里的maxn代表队列的最大长度,但为什么要做((rear+1)%maxn==front)的条件判断呢?
首先,取模操作无疑是为了使我们的队列“循环”起来。但是(rear+1)%maxn的目的是为了什么呢?
假设为(rear%maxn==front)为判断条件,可知有rear始终位于0~maxn之间,则存在将(rear%maxn==front)转化为(rear==front)的情况。因此,我们可能会将队满的情况判断为队空的情况(反之亦可)。
所以,在判断条件中给rear加上一个1是为了在对尾与队首之间隔出一个空位,以区分队满与队空两种情况。
OK,优化过程分析到这就结束了,下面见代码。
数组循环队列:

//循环队列 #include<iostream> #include<cstdlib> #include<cstring> # define maxn 10 using namespace std; int queue[maxn]; int front = 0;//队首指针 int rear = 0;//队尾指针 void add(int temp) { if((rear+1)%maxn==front) cout<<"The queue is full!"<<endl; else { queue[rear]=temp; rear=(rear+1)%maxn; } return; } int del() { if(front==rear) return -1; int temp=queue[front]; queue[front]=-1; front=(front+1)%maxn; return temp; } void display() { if(front==rear) cout<<"The queue is empty!"<<endl; else { int i=front; cout<<"front is : "<<front<<endl; cout<<"rear is : "<<rear<<endl; cout<<"The queue is : "; while(i!=rear) { cout<<queue[i]<<" "; i=(i+1)%maxn; } cout<<endl; } } int main() { int ins,temp; memset(queue,-1,sizeof(queue)); while(1) { cout<<"1.Input a data."<<endl; cout<<"2.Outout a data."<<endl; cout<<"3.Exit."<<endl; cin>>ins; switch(ins) { case 1 : cout<<"Please input a value : "; cin>>temp; add(temp); cout<<endl; break; case 2 : temp=del(); if(temp==-1) cout<<"The queue is Empty! "<<endl; else cout<<"The out value is : "<<temp<<endl; break; case 3 :return 0; } display(); system("pause"); system("cls"); } return 0; }
下面,为了对比,我简单给出链表模拟队列的代码,这里就不再赘述了。

//链表仿真队列 #include <iostream> #include <cstdlib> using namespace std; typedef struct QueueNode node; typedef struct QueueNode *link; struct QueueNode { int data; struct QueueNode *next; }; link front =NULL;//队头 link rear =NULL; //队尾 void addqueue(int value) { link new_node; new_node=(link)malloc(sizeof(node)); new_node->data=value; new_node->next=NULL; if(front==NULL) //若为队列第一个元素 front=new_node; else rear->next=new_node; rear=new_node; } int delqueue() { link top; int temp; if(front!=NULL) { top=front; front=front->next; temp=top->data; free(top); return temp; } else { rear=NULL; return -1; } } void display() { link point; point=front; cout<<"The queue is : "; while(point!=NULL) { cout<<point->data<<' '; point=point->next; } cout<<endl; } int main() { int select; int i,temp; while(1) { cout<<"1.Input a data\n"; cout<<"2.Output a data\n"; cout<<"3.Exit\n"; cin>>select; switch(select) { case 1:cout<<"Please input a value: "; cin>>temp; addqueue(temp); break; case 2:if(delqueue()==-1)//如果队列是空 cout<<"The queue is empty!\n"; else cout<<"The out value is: "<<temp<<endl; break; case 3:return 0; } display(); cout<<endl<<endl; system("pause"); system("cls"); } return 0; }
关于队列的讨论就到这里了,若有不足,请指正!