Queue | 循环队列的数组实现

我的未来我决定 提交于 2020-01-28 04:15:21

目录

 

一、概述

1、队列ADT

2、队列的基本操作

3、队列的实现方式

二、队列的数组实现

1、队列的结构

2、清空队列

3、创建一个初始化队列 

4、判断队列是否满

5、入队

6、判断队列是否为空

7、出队操作

 

 


一、概述

1、队列ADT

队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列是一种先进先出(First In First Out)的线性表。

允许插入的一端称为队尾,插入数据的操作称为入队

允许删除的一端称为队头,删除数据的操作称为出队

这里写图片描述

 

2、队列的基本操作

CreatQueue()    ——初始化队列
MakeQueueEmpty   ——清空队列
EnQueue()        ——进队列
DeQueue()        ——出队列
IsQueueEmpty()   ——判断队列是否为空
IsQueueFull()    ——判断队列是否已满

3、队列的实现方式

队列可以由数组链表两种形式实现队列操作。分别称为顺序队列链队列

且顺序队列还可以实现循环,已增加空间的利用。

下面均讨论顺序循环队列

二、队列的数组实现

1、队列的结构

typedef struct QueueRecord {
    int Capacity; //队列容积
    int Front;  //队头下标
    int Rear;  //队尾下标
    int *array;  //数据域
} *Queue, queue;

2、清空队列

这个很重要,为了方便起见,默认队列为空时,队头在0,队尾在-1

每个人习惯不同,可以不一样(有的人会将初始队尾设置为0),但是后面的操作也要对应改变。

 

每当插入新的队列尾元素时,“尾指针增1”

每当删除队列头元素时,“头指针增1”。

因此,非空队列中,队头始终指向队列头元素队尾始终指向队列尾元素另:队尾指向队列末尾元素的下一个

void MakeQueueEmpty(Queue Q) {
    Q->Front = 0;
    Q->Rear = -1;
}

3、创建一个初始化队列 

Queue CreatQueue (int MaxElement) {
    Queue Q = (Queue)malloc(sizeof(queue));
    Q->array = (int *)malloc(sizeof(int)*MaxElement);
    Q->Capacity = MaxElement;
    MakeQueueEmpty(Q);   //初始化清空队列
    return Q;
}

 

4、判断队列是否满

如何判断一个循环队列是否满的? 不如这样理解:

假设我们在军训中排队,每个人报数。一个队列只能站10个人,从1报到10,队就满了。后来呢,队头的两个人出队了,然后又补充了两个新队员,那么这时候的报数是3到12。这时队列也是满的。

两种情况下判断队满的条件分别为:

(10 + 1) % 10 = 1
(12 + 1) % 10 = 3

所以很容易发现队列满的条件就是 :

(rear+1) % Capacity == front 

int QueueIsFull(Queue Q) {
    return (Q->Rear + 1) % Q->Capacity == Q->Front;
}

5、入队

 先要判断是否队列已满。

入队:队尾后移出一位并赋值。

需要注意的是,这里实现的时循环队列,所以当队尾移至超出数组下标界限时,要将其移至数组的开始,以实现循环储存

void Enqueue(int x, Queue Q){

    if (QueueIsFull(Q))  //队列已满
        return;

    if(++ Q->Rear == Q->Capacity)  //队尾后移一位,若到数组末端,至于最前
        Q->Rear = 0;
    Q->array[Q->Rear] = x;  //入队
}

6、判断队列是否为空

int QueueIsEmpty(Queue Q) {
    return Q->Rear + 1 == Q->Front;
}

7、出队操作

注意不要对空队列进行出队操作,先要判断队列是否为空。

void Dequeue(Queue Q) {
    if(QueueIsEmpty(Q))
        return;
    if (++Q->Front == Q->Capacity) //队首后移一位(相当于删除队首)
        Q->Front = 0;
}

 



End

欢迎关注个人公众号“鸡翅编程”,这里是认真且乖巧的码农一枚,旨在用心写好每一篇文章,平常会把笔记汇总成推送更新~

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!