【数据结构】队列

什么是队列

队列(Queue):具有一定操作约束的线性表
插入和删除操作:只能在一端插入,而在另一端删除

数据插入:入队列(AddQ)
数据删除:出队列(DeleteQ)
先来先服务
先进先出:FIFO

队列的抽象数据类型描述

类型名称:队列(Queue)
数据对象集:一个有0个或多个元素的有穷线性表。
操作集:长度为MaxSize的队列 Q ∈ Q u e u e Q\in Queue QQueue, 队列元素 i t e m ∈ E l e m e n t T y p e item\in ElementType itemElementType

Queue CreatQueue(int MaxSize):   生成长度为MaxSize的空队列;
int IsFullQ( Queue Q, int MaxSize ):  判断队列Q是否已满;
void AddQ( Queue Q, ElementType item): 将数据元素item插入队列Q中;
int IsEmptyQ( Queue Q):   判断队列Q是否为空;
ElementType DeleteQ( Queue Q):  将队列头数据元素从队列中删除并返回。

队列的顺序存储实现

队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成。

#define MaxSize <储存数据元素的最大个数>
struct QNode{
    ElementType Data[ MaxSize ];
    int rear;
    int front;
};
typedef struct QNode *Queue;

一个平铺的工作队列:
Rear负责向队列中插入元素,Front负责删除。当队列为空时,Rear与Front相等
在这里插入图片描述
一个循环队列:
在这里插入图片描述
对于上面一种队列,可以通过Rear与Front是否相等来判断队列是否为空,但对于循环队列,Rear与Front相等时既有可能是空的,也有可能是满的。
解决方案:
a.使用额外标记:Size或者tag域
b.仅使用n-1个数组空间

(1)入队列
我们首先判断队列是不是满的。队列用一个结构指针PtrQ来表示
首先用rear+1求余,如果等于front表示队列满了。

void AddQ( Queue PtrQ, ElementType item)
{
    if((PtrQ->rear+1)%MaxSize == PtrQ->front){
        printf("队列满");
        return;
    }
    PtrQ->rear = (PtrQ->rear+1)%MaxSize;
    PtrQ->Data[PtrQ->rear] = item;
}

(2)出队列

ElementType DeleteQ( Queue PtrQ )
{
    if(PtrQ->front == PtrQ->rear){
        printf("队列空");
        return ERROR;
    }else{
        PtrQ->front = (PtrQ->front+1)%MaxSize;
        return PtrQ->Data[PtrQ->front];
    }
}

队列的链式存储实现

队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行;
队列指针front和rear应该分别指向链表的哪一头?

struct Node{
    ElementType Data;
    struct Node *Next;
};
struct QNode{    /*链队列结构*/
    struct Node *rear;    /*指向队尾结点*/
    struct Node *front;   /*指向队头结点*/
};
typedef struct QNode *Queue;
Queue PtrQ;

在这里插入图片描述

ElementType DeleteQ( Queue PtrQ )
{
    struct Node *FrontCell;
    ElementType FrontElem;
    if(PtrQ->front == NULL){
        printf("队列空");  return ERROR;
    }
    FrontCell = PtrQ->front;       
    if(PtrQ->front  == PtrQ->rear)    /*若队列只有一个元素*/
        PtrQ->front == PtrQ->rear = NULL/*删除后队列置为空*/
    else
        PtrQ->front = PtrQ->front->Next;
    FrontElem = FrontCell->Data;
    free( FrontCell );           /*释放被删除结点空间*/
    return FrontElem;
}

其中 FrontCell = PtrQ->front;就是找到队列头的位置,圈起来的就是FrontCell。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值