队列的实现

来源:互联网 发布:淘宝客服问答 编辑:程序博客网 时间:2024/06/06 03:24

队列(Queue)是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。(先进先出)


队列有两种表现形式:1.用链表的形式

                                    2.用数组的形式


队列的结构图:

1.链表表达的队列结构图:当队列为空队列的时候,队列的头指针和尾指针相等(Q.front=Q.rear=0)

在非满队列的情况下:队列的头指针(front)所指向的地址不带数据。每插入一个数,队列的尾指针(rear)增加1。当队列长度到达队列的容量时,将不再增加。删除队列中的元素时,每删除一个,头指针增加1.


2.数组表达的循环队列

在实际使用队列时,为了使队列空间能重复使用,往往对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。自己真从MaxSize-1增1变到0,可用取余运算rear%MaxSize和front%MaxSize来实现。这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列。除了一些简单应用之外,真正实用的队列是循环队列。


代码实现:

1.数组表达(循环队列):

#include<iostream>#define MAXSIZE 10                            //队列的容量using namespace std;typedef struct {                              //定义一个队列结构体int *base;                                //定义一个数组,用来储存数据int front;                                //队列的头指针int rear;                                 //队列的尾指针int count;                                //计数器,储存队列的长度,方便下面的操作,判断}SqQueue;void InitSqQueue(SqQueue &Q) {                //初始化队列Q.base = (int *)malloc(MAXSIZE * sizeof(int));if (!Q.base)cout << "OVERFLOW!" << endl;Q.front = 0;Q.rear = 0;Q.count = 0;}bool Full_Queue(SqQueue &Q) {               //判断队列是否满了if (Q.count != MAXSIZE)return false;else return true;}void Create_Queue(SqQueue &Q) {                        //生成一个队列int date = 1;while (date) {cout << "Please enter the date you wanna enter(date<=0 for end):";cin >> date;if (date) {if (Full_Queue(Q)) {cout << "The queue is full!" << endl;break;}else {Q.base[Q.rear] = date;Q.rear = (Q.rear + 1) % MAXSIZE;           //取余,确保rear的值不超过MAXSIZE,以此保证指针在超过队列容量时能够指回队列的头部,形成循环Q.count++;}}}}void En_Queue(SqQueue &Q,int element) {                    //在队列后面插入指定元素if (Full_Queue(Q)) cout << "The queue is full!" << endl;else {Q.base[Q.rear] = element;Q.rear = (Q.rear + 1) % MAXSIZE;Q.count++;}}void De_Queue(SqQueue &Q) {                               //删除队列前面的元素if (Q.count==0) cout << "The queue is empty!" << endl;else {Q.front = (Q.front + 1) % MAXSIZE;Q.count--;}}void Queue_traverse(SqQueue &Q) {                      //遍历队列if (Q.count==0) cout << "The queue is empty!" << endl;else {int i = 0;for (i; i < Q.count; ++i) cout << Q.base[(Q.front + i)%MAXSIZE] << " ";cout << endl;}}void main() {SqQueue Q;InitSqQueue(Q);Create_Queue(Q);Queue_traverse(Q);De_Queue(Q);Queue_traverse(Q);En_Queue(Q, 100);Queue_traverse(Q);system("pause");}

2.链表表达(非循环):
#include<iostream>using namespace std; typedef struct Node{int Date;struct Node *next;}Node,*QueuePr;typedef struct {QueuePr front;QueuePr rear;}LinkQueue;void InitQueue(LinkQueue &Q) {                       //初始化Q.front = NULL;if (Q.front != NULL) cout << "OVERFLOW" << endl;Q.rear = Q.front;}int QueueLength(LinkQueue &Q) {                     //队列长度QueuePr p;p = (Node *)malloc(sizeof(Node));p = Q.front;int i = 0;if (!Q.front)return 0;for (i; p != Q.rear; ++i) p = p->next;return i;}void EnQueue(LinkQueue &Q) {                              //插入操作QueuePr p;int date = 1;while (date) {cout << "Please enter the date you wanna enter(date<=0 for end):";cin >> date;if (date) {p = (Node *)malloc(sizeof(Node));p->Date = date;p->next = NULL;if (!QueueLength(Q)) {Q.front = (Node *)malloc(sizeof(Node));Q.rear = (Node *)malloc(sizeof(Node));Q.front->next = p;Q.rear = p;}else {Q.rear->next = p;Q.rear = p;}}}}void QueueTraverse(LinkQueue &Q) {                             //遍历队列QueuePr p;p = (Node *)malloc(sizeof(Node));p = Q.front;if (Q.front==Q.rear) cout << "The queue is empty!" << endl;else {while (p->next) {cout << p->next->Date << " ";p = p->next;}cout << endl;}}void DeQueue(LinkQueue &Q) {                         //删除列头一个元素QueuePr p;p = (Node *)malloc(sizeof(Node));p = Q.front->next;if (Q.front == NULL) cout << "The queue is empty!" << endl;else {Q.front->next = p->next;delete p;}}bool QueuEmpty(LinkQueue &Q) {                     //判断是否为空队列if (!Q.front)return true;else return false;}void main() {LinkQueue Q;InitQueue(Q);if (QueuEmpty(Q)) cout << "The queue is empty!" << endl;EnQueue(Q);cout << "Length:" << QueueLength(Q) << endl;QueueTraverse(Q);DeQueue(Q);cout << "Length:" << QueueLength(Q) << endl;QueueTraverse(Q);system("pause");}



0 0