欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(三)队列(queue)

程序员文章站 2022-06-08 08:12:36
...

队列也是具有一定操作约束的线性表。它和堆栈不同,它只可在一端插入(Add),另一端删除(Delete)

其主要特征是先进先出

一、队列的抽象数据类型描述

        数据对象集:一个有零个或多个元素的有穷线性表

        操作集:生成一个队列、判断队列是否已满、插入、判断队列是否为空、删除、

二、队列的顺序存储

        队列的顺序存储最简单的方法是用数组进行存储,可以用一个一维数组还有两个变量front和rear来存储数组。但是这种方法随着出队入队操作的进行,会使整个队列整体想前、后移动。有时候可能会造成“假溢出”的现象。

(三)队列(queue)

为解决这个问题我们在队列的顺序存储中一般采用循环队列的方式:rear和front到达数组端点时,能折回到数组开始处。

采用这种方法第一个要考虑的问题时如何初始化front和rear

可以将front和rear都初始化为0,插入一个元素时rear加1,删除一个元素时front加1

但是这种方法又存在了一个问题,当front等于rear时是表示队列为空还是队列为满呢

为解决这个问题可以用两个方法,第一种,可以增加一个变量tag来标记最后一次操作是删除还是插入;第二种,可以只存储n-1个元素,最后一个元素不用考虑,这样一来队列空的条件仍然是:rear等于front,队列满的条件就会是:(rear+1)%数组长度等于front

实现结构的代码表述如下:

#define MaxSize <100>

typedef struct
{
    ElementType Data[MaxSize];
    int rear;
    int front;
}Queue;

插入操作代码实现:

void AddQ(Queue *PtrQ,ElementType item)
{
    if ((PtrQ->rear+1)%MaxSize==PtrQ->front)     //判断队列是否已满
    {
        printf("队列已满");
        return;
    }
    PtrQ->rear = (PtrQ->rear+1)%MaxSize;    //队尾加1
    PtrQ->Data[PtrQ->rear] = item;     //数据存入Data中
}

删除操作代码实现:

ElementType DeleteQ(Queue *PtrQ)
{
    if (PtrQ->rear == PtrQ->front)     //判断队列是否为空
    {
        printf("队列为空");
        return ERROR;
    }
    else
    {
        PtrQ->front = (PtrQ->front-1)%MaxSize;    //队首减1
        return PtrQ->Data[PtrQ->front];
    }
}

三、队列的链式存储

        队列链式存储时,队列的头必须指向链表的头结点,队列的尾必须指向链表的尾节点

        代码实现:

typedef struct Node *PtrToNode;
struct Node { /* 队列中的结点 */
    ElementType Data;
    PtrToNode Next;
};
typedef PtrToNode Position;
 
struct QNode {
    Position Front, Rear;  /* 队列的头、尾指针 */
    int MaxSize;           /* 队列最大容量 */
};
typedef struct QNode *Queue;
 
bool IsEmpty( Queue Q )
{
    return ( Q->Front == NULL);
}
 
ElementType DeleteQ( Queue Q )
{
    Position FrontCell; 
    ElementType FrontElem;
     
    if  ( IsEmpty(Q) ) {
        printf("队列空");
        return ERROR;
    }
    else {
        FrontCell = Q->Front;
        if ( Q->Front == Q->Rear ) /* 若队列只有一个元素 */
            Q->Front = Q->Rear = NULL; /* 删除后队列置为空 */
        else                     
            Q->Front = Q->Front->Next;
        FrontElem = FrontCell->Data;
 
        free( FrontCell );  /* 释放被删除结点空间  */
        return  FrontElem;
    }
}

 

相关标签: Datastruct Queue