队列
顺序表示
队列的顺序存储结构,用一组地址连续的存储单元依次存放从队列头和队列尾的元素之外,还需要附设两个整型变量front和rear分别表示队列头元素和队列尾元素的位置。
初始化创建空队列,令front=rear=0。每当插入新的队尾元素时,尾指针rear增1;每当删除队列头元素时,头指针front增1。
在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置。
typedef struct{ QElemType *base; //存储空间的基地址 int front; //头指针 int rear; //尾指针 }SqQueue;
循环队列的实现和使用
队尾入队、队头出队会造成假溢出。可以使用循环队列解决这种问题。
循环队列判断队满和队空的方法:
- 少用一个元素空间,即队列空间大小为m时,有m-1个元素就认为是队满。当头、尾指针的值相同时,则认为队空。当尾指针在循环意义上加1后是等于头指针,则认为队满。
队空的条件:Q.front==Q.rear
队满的条件:(Q.rear+1)%MAXQSIZE==Q.front
#include<iostream> using namespace std; #define MAXQSIZE 100 //队列可能达到的最大长度 typedef int QElemType; typedef int SElemType; typedef struct{ QElemType *base; //存储空间的基地址 int front; //头指针 int rear; //尾指针 }SqQueue; //初始化 void InitQueue(SqQueue &Q){ //构造一个空队列Q Q.base=new QElemType[MAXQSIZE]; //分配最大容量的数组空间 if(!Q.base) perror("分配失败"); Q.front=0; Q.rear=0; //头指针和尾指针置为0.队列为空 } //求队列长度 int QueueLength(SqQueue Q){ //返回Q的元素个数,即队列的长度 return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE; } //入队 在队尾插入一个新的元素 void EnQueue(SqQueue &Q,QElemType e){ //少用一个元素 即队列空间大小为m时,有m-1个元素就认为是队满 if((Q.rear+1)%MAXQSIZE==Q.front){ perror("队列满了"); } Q.base[Q.rear]=e;//新元素插入队尾 Q.rear=(Q.rear+1)%MAXQSIZE;//队尾指针加1 } //出队 void Dequeue(SqQueue &Q,QElemType &e){ //删除Q的队头元素,用e返回其值 if(Q.front==Q.rear) perror("队空"); e=Q.base[Q.front]; //保存队头元素 Q.front=(Q.front+1)%MAXQSIZE; //队头指针加1 } //取队头元素 SElemType GetHead(SqQueue Q){ //返回Q的队头元素,不修改队头指针 if(Q.front!=Q.rear){ //非空 return Q.base[Q.front]; //返回队头元素的值,队头指针不变 }else{ return -1; } } //遍历整个队列 void Traverse(SqQueue Q){ int len=QueueLength(Q); for(int i=0;i<len;i++){ printf("%d ",Q.base[i]); } } int main(){ int item,top; SqQueue Q; InitQueue(Q); while(scanf("%d",&item)!=EOF){ EnQueue(Q,item); } EnQueue(Q,1); Dequeue(Q,top); printf("%d\n",top); Traverse(Q); return 0; }
链式表示和实现
一个链队需要两个分别指示队头和队尾的指针才能唯一确定。
为方便起见,给链队添加一个头结点,并令头指针始终指向头结点。
#include<iostream> using namespace std; typedef int QElemType; typedef int SElemType; typedef struct QNode{ QElemType data; struct QNode *next; }QNode,*QueuePtr; typedef struct{ QueuePtr front; //队头指针 QueuePtr rear; //队尾指针 }LinkQueue; //初始化 void InitQueue(LinkQueue &Q){ //构造一个空队列Q Q.front=Q.rear=new QNode; //生成新结点作为头结点,队头和队尾指针指向此结点 Q.front->next=NULL; //头结点的指针域指空 } //入队 void EnQueue(LinkQueue &Q,QElemType e){ //插入元素e为Q的新的队尾元素 QNode *p=new QNode; p->data=e; p->next=NULL; Q.rear->next=p; //将新结点插入到队尾 Q.rear=p; } //出队 void DeQueue(LinkQueue &Q,QElemType &e){ //删除Q的队头元素、用e返回其值 if(Q.front==Q.rear) perror("队列空"); QNode *p=Q.front->next; //p指向队头元素 e=p->data; Q.front->next=p->next; //修改头指针 if(Q.rear==p) Q.rear=Q.front; //最后一个元素被删,队尾指针指向头结点 delete p; } //取队头元素 SElemType GetHead(LinkQueue Q){ if(Q.front!=Q.rear) return Q.front->next->data; else return -1; } //遍历整个队列 void TraverseQueue(LinkQueue Q){ QNode *p=Q.front->next; while(p!=NULL){ printf("%d ",p->data); p=p->next; } } int main(){ LinkQueue Q; InitQueue(Q); int item,elem; while(scanf("%d",&item)!=EOF){ EnQueue(Q,item); } DeQueue(Q,elem); printf("%d\n",elem); TraverseQueue(Q); return 0; }