简洁的介绍什么是队列和使用

512 阅读2分钟

我正在参加「掘金·启航计划」

1.队列的定义

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

image.png

  • 入队就是插入操作
  • 出队就是删除操作

特点: 先进先出(FIFO)

重要术语:队头、队尾、空队列

  • 队头:允许删除的一端
  • 队尾:允许插入的一端
  • 空队列:没有任何数据元素

2.队列的基本操作

  • InitQueue(&Q):初始化队列,构造一个空队列Q
  • DestoryQueue(&Q):销毁队列,销毁并释放队列Q所占用的内存空间
  • EnQueue(&Q,x):入队,若队列Q未满,将x加入,使之成为新的队尾
  • DeQueue(&Q,&x):出队,若队列Q非空,删除队头元素,并用x返回
  • GetHead(Q,&x):读对头元素,若队列Q非空,则将队头元素赋值给x

3.队列的顺序实现

用静态数组存放队列元素,在定义一个队头指针,一个队尾指针

#define Maxsize 10
typedef struct{
    ElemType data[MaxSize];
    int front;
    int rear;
}SqQueue;

3.1初始化操作

初始化队列:

void InitQueue(SqQueue &Q){
    Q.rear=Q.front=0;    //初始队头、队尾指针指向0
}

判断队列是否为空:

bool QueueEmpty(SqQueue Q){
    Q.rear==Q.front
        return true
    return false;
}

3.2入队操作

入队操作只能从队尾入队;实现分析:需要先判断队列是否为满,然后将新元素插入队尾,然后修改队尾的指针后移。

bool EnQueue(SqQueue &Q,ElemType x){
    if(队列已经满)
        return false;
    Q.dara[Q.rear]=x;
    Q.rear=Q.rear+1;   
        return true;
}

3.2.1方案一(判空)

如果直接给队尾指针直接后移是会出问题的,当整个静态数组被存满的时候,rear指针就会指向MaxSize,如果依次让对头出队的时候,rear依然是指向MaxSize,所以rear==MaxSize的条件不能判断队列已经满了。所以需要修改为:让队尾指针+1后取模

Q.rear=(Q.rear+1)%MaxSize;

用模运算将储存空间在逻辑上变成了“环状”

image.png

3.2.2方案二(判空)

用size记录队列的当前长度,初始化size为0。

int size=0;  //初始化时候
size++;   //插入成功
size--;   //删除成功
队列空:size=0;
队列为满:size==MaxSize

3.2.3方案三(判空)

标记位,删除成功的时候tag=0,插入成功的时候tag=1

  • 队列满:front==rear && tag==1
  • 队列空:front==rear && tag==0

3.3出队操作

删除一个队列头元素,并且用x返回

bool DeQueue(SqQueue &Q,ElemType &X){
    if(Q.rear==Q.front)   //判断队列是否为空
        return false;
    x=Q.data[Q.front];
    Q.front=(Q.front+!)%MaxSize;  //队列头指针后移
}

3.4 查队头元素

获得队列头元素值并用x返回

bool GetQueue(SqQueue Q,ElemType &X){
    if(Q.rear==Q.front)   //判断队列是否为空
        return false;
    x=Q.data[Q.front];
    return true;
}