数据结构第十篇——顺序队列

Posted T丶jl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构第十篇——顺序队列相关的知识,希望对你有一定的参考价值。

和栈相反,队列(queue)是一种先进先出(First In First Out,FIFO)的线性表。它只允许在表的一端进行插入,而在另一端删除元素、这和我们日常生活中的排队是一致的,最早进入队列的元素最早离开。在队列中,允许插入的一端叫做队尾(rear),允许删除的一端称为队头(front)。

队列在程序设计中也经常出现。一个最典型的例子就是操作系统中的作业排队。

在允许多道程序运行的计算机系统中,同时有借个作业运行。如果运行的结果都需要通过通道输出,那就要按请求输出的先后次序排队。每当通道传输完毕可以接收新的输出任务时,队头的作业先从队列中退出,做输出操作。凡是申请输出的作业都从队尾进入队列。

队列的操作与栈的操作类似,不同的是删除在表的头部(即队头)进行。

队列的实现

与线性表、栈类似,队列也有顺序存储和链式存储两种存储方式这篇主要介绍顺序队列,链队列请转至。

在队列的顺序存储结构中,与顺序栈类似,用数组存放表中元素,另外设置两个指针分别指向队头和队尾的位置。顺序队定义如下:

 

 1 const int MaxQSize=50;
 2 class Queue
 3 {
 4     int front;
 5     int rear;
 6     Data QueueList[MaxQSize];
 7     
 8     public:
 9         Queue();                    //初始化数据成员 
10         ~Queue();
11         
12         void EnQueue(Data item);            //入队 
13         Data DeQueue();            //出队 
14         Data GetFront();            //取队头元素值 
15         void ClearQueue();            //清空队列 
16         bool IsEmpty();                //判断空否 
17         bool IsFull();                    //判断满否 
18         int  Length();                 //求元素个数 
19 };

  我们约定:初始化建立空队时,令front=rear=0;每当队尾插入新元素时,“尾指针增1”;每当队头删除一个元素时,“头指针增1”。因此头指针front总是指向队头元素,队尾指针rear总是指向队尾元素的下一个位置(这样设置是为了某些运算的方便,并不是唯一的方法);判断队空的条件是队头指针和队尾指针相同。
  随着入队出队的进行,会使整个队列整体向后移动,这样就出现了队尾指针已经移到了最后,再有元素入队就会出现溢出,而事实上此时队中并未真的“满员”,这种现象为“假溢出”,这是由于队尾入,队头出的受限操作,以及为避免数据元素移动,队头队尾不固定造成的。

解决假溢出的方法有:

①固定队头,出队后,队列中的所有元素向前移动。

②固定队尾,入队时,队列中的所有元素向前移动。

③将队列的数据区看成头尾相接的循环结构,头尾指针的关系不变,将其称为“循环队列”。

  前两种方法在入队和出队时需要移动队列中所有元素,第三种方法则不需要移动数据元素,是一种更好的方法。

循环队列的算法操作算法描述如下:

 1 Queue::Queue()
 2 {
 3     front=rear=0;
 4 }
 5 
 6 //入队操作 
 7 void Queue::EnQueue(Data item)
 8 {
 9     if((rear+1)%MaxQSize==front)
10     {
11         cout<<"队列已满"<<endl;
12         exit(0);
13     } 
14     else
15     {
16         QueueList[rear]=item;
17         rear=(rear+1)%MaxQSize;
18     }
19 }
20 
21 //出队操作
22 Data Queue::DeQueue()
23 {
24     if(front==real)
25     {
26         cout<<"队列已空"<<endl;
27         exit(0);
28     }
29     Data e=QueueList[front];
30     front=(front+1)%MaxQSize;
31     return e;
32 } 
33 
34 //清空队列
35 void Queue::ClearQueue() 
36 {
37     rear=front;
38 }
39 
40 //判断空否
41 bool Queue::IsEmpty()
42 {
43     if(rear==front)    return true;
44     else                    return false;
45 } 
46 
47 //判断满否
48 bool Queue::IsFull()
49 {
50     if((rear+1)%MaxQSize==front)    return true;
51     else                                    return false;
52 } 
53 
54 //取队头元素值
55 inline Data Queue::GetFront()
56 {
57     return QueueList[front];
58 } 
59 
60 //析构函数
61 inline Queue::~Queue()
62 {
63     return (rear-front+MaxQSize)%MaxQSize;
64 } 

以上操作都与队列中元素个数无关,时间复杂度为O(1)。
v、

以上是关于数据结构第十篇——顺序队列的主要内容,如果未能解决你的问题,请参考以下文章

Python开发第十篇:RabbitMQ队列

PerfView专题 (第十篇):洞察 C# 终结队列引发的内存泄漏

Linux从青铜到王者第十篇:Linux进程间通信第二篇

第十篇 面向对象的程序设计

开始写游戏 --- 第十篇

Python进阶第十篇模块(上)