• 数据结构-王道2017-第3章 栈和队列-队列


    1.队列简称队,也是一种操作受限的线性表,只允许在表的一端插入,而在表的另一端删除 先进先出FIFO,不能随便读取队列中间的某个数据

       队头(Front):允许删除的一端,又称为队首

       队尾(rear):允许插入的一端

       空队列:不含任何元素的空表

       基本操作: InitQueue(&Q),QueueEmpty(Q),EnQueue(&Q,x),DeQueue(&Q,&x),GetHead(Q,&x)

    2.队列的顺序存储

     设队头指针指向队头元素,队尾指针指向队尾元素的下一个位置(队头指针指向队头元素的钱一个位置,队尾指针指向队尾也可以)

    typedef struct {
        ElemType data[MaxSize];
        int front, rear;
    }SqQueue;

    队空条件:Q.front == Q.rear == 0;

     但是队满条件不能是Q.rear==MaxSize,因为当front == Q.rear-1时,仍然妈祖条件,但此时队中只有一个元素,此时入队出现“上溢出”,但这种溢出并不是真正的溢出,这是顺序队列的缺点

    3.循环队列

      当队首指针Q.front=MaxSize-1后,再前进一个位置就自动到0,这可以利用除法取余运算(%)来实现

      初始时:Q.front=Q.rear=0

      队首指针进1:Q.front=(Q.front+1)%MaxSize;

      队尾指针进1:Q.rear=(Q.rear+1)%MaxSize;    

      队列长度: (Q.rear+MaxSize - Q.front)%MaxSize;    //加上MaxSize的原因是Q.rear可能循环到Q.front的左边,这时长度就是Q.rear+MaxSize - Q.front,%MaxSize的目的是Q.rear在Q.front的右边时,加上MaxSize就不是准确值了,所以取模,而取模对前一种情况是没有影响的

     出队入队时:指针都按顺时针方向进1

     且队空的条件为Q.front=Q.rear,而队满的条件也是Q.front=Q.rear(队尾指针追上了队首指针),解决方案:

        1)牺牲一个单元来区分队空队满,入队时少用一个队列单元,这是一种较为普遍的做法,约定以“队头指针在队尾指针的下一个位置作为队满的标志”。

               队满条件:(Q.rear+1)%MaxSize==Q.front 

               队空条件:Q.front==Q.rear

               队列中元素的个数:(Q.rear-Q.front+MaxSize)%MaxSize

        2) 类型中增设表示元素个数的数据成员。这样队空的条件为Q.size == 0;队满的条件为Q.size==MaxSize,两种情况都有Q.front==Q.rear

        3) 类型中增设tag数据成员,以区分堆满还是队空。tag等于0的情况下,若因删除导致Q.front==Q.rear则为队空,tag等于1的情况下,若因插入导致Q.front==Q.rear则为队满

    3.循环队列的操作

    //队列的顺序存储结构
    const int MaxSize = 50;
    
    typedef int ElemType;
    
    
    typedef struct {
        ElemType data[MaxSize];
        int front, rear;
    }SqQueue;
    
    void InitQueue(SqQueue &q) {
        q.front = q.front = 0;
    }
    
    bool QueueEmpty(SqQueue q) {
        return q.rear == q.front;
    }
    
    bool EnQueue(SqQueue &q,ElemType x) {
        if ((q.rear + 1) % MaxSize == q.front)
            return false;
        q.data[q.rear] = x;
        q.rear = (q.rear + 1) % MaxSize;
        return true;
    }
    
    bool DeQueue(SqQueue &q, ElemType &x) {
        if (q.front == q.rear)   //队列为空
            return false;
        x = q.data[q.front];
        q.front = (q.front + 1) % MaxSize;
        return true;
    }

     4.队列的链式存储结构

    typedef struct{
        ElemType data;
        LinkNode *next;
    }LinkNode;    //注意不是指针
    
    typedef struct {
        LinkNode *front, *rear;
    }LinkQueue;

    队列的判空条件为:Q.front==NULL&&Q.rear==NULL,通常将链式队列设计成一个带头节点的单链表,这样插入和删除操作就统一了,不存在队满且产生溢出的问题

    //队列的顺序存储结构
    const int MaxSize = 50;
    
    typedef int ElemType;
    
    typedef struct{
        ElemType data;
        LinkNode *next;
    }LinkNode;    //注意不是指针
    
    typedef struct {
        LinkNode *front, *rear;
    }LinkQueue;
    
    void InitQueue(LinkQueue &q) {
        q.rear = q.front = (LinkNode*)malloc(sizeof(LinkNode));
        q.front->next = NULL;
    }
    
    bool QueueEmpty(LinkQueue q) {
        return q.rear == q.front;
    }
    
    void EnQueue(LinkQueue &q,ElemType x) {
        LinkNode *p = (LinkNode*)malloc(sizeof(LinkNode));
        p->data = x;
        p->next = NULL;
        q.rear->next = p;
        q.rear = p;
    }
    
    bool DeQueue(LinkQueue &q, ElemType &x) {
        if (q.rear == q.front)
            return false;
        LinkNode *p = q.front->next;
        x = p->data;
        q.front->next = p->next;
        if (p == q.front)    //只有一个元素的时候要置尾指针为空
            q.rear = q.front;    
        free(p);
        return true;
    }

     5.双端队列

      双端队列:指允许两段都可以进行入队和出队操作的队列,其元素的逻辑结构仍然是线性结构,两端分别称为前端和后端

      输出受限的双端队列:允许在一端进行插入和删除,但在另一端只允许插入的双端队列称为输出受限的双端队列

      输入受限的双端队列:允许在一端进行插入和删除,但在另一端只允许删除的双端队列称为输入受限的双端队列 

      如果限定双端队列从某个端点插入的元素只能从该端点删除,则该双端队列就蜕变为两个栈底相邻接的栈了

        

    6.试题精选

      1)栈和队列都只能顺序存取

      2)进队操作,只有尾指针变化,出队操作除了队中只有一个元素外(也会更改rear指针),只会更改front指针

  • 相关阅读:
    【LeetCode & 剑指offer刷题】数组题18:Plus One
    SQL Server 2005 的动态管理视图DMV和函数DMF
    数据库SQL优化大总结之 百万级数据库优化方案
    误删SQL Server日志文件后怎样附加数据库
    教你建立SQL数据库的表分区
    Sql Server 阻塞的常见原因和解决办法
    SQL索引优化方法
    详解如何定义SQL Server外关键字约束
    写出高性能SQL语句的十三条法则
    SQL SERVER内部函数大全
  • 原文地址:https://www.cnblogs.com/--CYH--/p/6554442.html
Copyright © 2020-2023  润新知