首页 > 其他分享 >队列总结_legend

队列总结_legend

时间:2022-12-18 19:31:12浏览次数:42  
标签:总结 4.3 队列 next 出队 front legend rear






队列总结:Queue



 



(1)队列的基本知识:



        (1.1)特点:尾进头出,先进先出。(rear in front out)



 



        (1.2)与线性表比较:



        队列是一种插入,删除操作受限的线性表,插入元素的一端为队尾,删除元素的一端为队头。队列中数据元素之间的逻辑关系与线性表中数据元素之间的逻辑关系完全相同,但是他们的运算是不同的。



 



(2)队列的基本操作:



        初始化,判队空,进队,出队。



 



(3)顺序队的基本操作:SequenceQueue



        (3.1)顺序队列图解:



队列总结_legend_循环队列



        (3.2)顺序队列的缺陷:



        队头队尾指针只会增加不会减少,导致被出队元素的空间无法重新利用。



 



(4)顺序循环队列的基本操作:SeCycleQueue



 



        (4.1)循环队列图解:



队列总结_legend_出队_02



        (4.2)循环队列讲解:



 



                  循环队列的类型定义如下:



 



                  typedefstruct{



                  qElemTypedata[MaxSize];



                  intfront;



                  intrear;



                  }SeQueue;



 



        (4.3)循环队列要素:



                  (一)方法一:



                  (4.3.0)front,rear涵义:



 



                  front:指向队列中队头元素的前一个元素:



                  rear:指向队尾元素:



                  注: rear所指的位置以及填上元素了,所以进队时,rear先后移,然后再赋值。



                  front:指向队头的前一个位置,所以出队,front先后移,然后在赋值。



                  (4.3.1)初始化循环队列:front=rear=-1;



                  (4.3.2)队空:front==rear;



                  (4.3.3)队满:front==(rear+1)%MaxSize;



                  /*rear的下一个位置就是front*/



 



                  (4.3.4)元素elem进队:



                 rear=(rear+1)%MaxSize;



                  data[rear]=elem;



 



                  (4.3.5)出队:



                  front=(front+1)%MaxSize;



                  elem=data[front];



 



                  (4.3.6)队长:



                  len=(rear-front+MaxSize)%MaxSize;



 



                  扩展:已经知道fornt,len求rear:



                  rear=(front+len)%MaxSize;



                  front=(rear-len+MaxSize)%MaxSize;



 



                  (4.3.7)取队头:



                  index=(front+1)%MaxSize;



                  elem=data[index];



                  returnelem;



 



                  (二)方法二:



                  (4.3.0)front,rear涵义:



 



                  rear这个位置还没有填写元素;



                  front这个位置已经填写了元素;



                  所以:进队,先赋值,然后rear++;



                  出队:先赋值,然后front++;



                  (关键是入队与出队对应。其实先++与先赋值没有限定)



 



                  (4.3.1)初始化循环队列:front=rear=0;



                  (4.3.2)队空:front==rear;



                  (4.3.3)队满:front=(rear+1)%MaxSize;



                  (4.3.4)元素elem进队:



                  data[rear]=elem;rear=(rear+1)%MaxSize;



                  (4.3.5)出队:



                  elem=data[front];front=(front+1)%MaxSize;



                  (4.3.6)队长:



                  len=(rear-front+MaxSize)%MaxSize;



                  (4.3.7)取队头:elem=data[front];



 



        (4.4)循环队列基本操作代码实现:以及变形的循环队列之代码实现:



        






 



        



        (4.5)循环队列补充:



        (4.5.1)循环队列的基本操作:



    循环队列中进行出队、入队操作时,头尾指针仍要加1,朝前移动。只不过当头尾指针指向向量上界(QueueSize-1)时,其加1操作的结果是指向向量的下界0。这种循环意义下的加1操作可以描述为:



①方法一:



   if(i+1==QueueSize) //i表示front或rear



       i=0;



   else



       i++;



 



②方法二--利用"模运算"



   i=(i+1)%QueueSize;



   (4.5.2)循环队列的类型定义



 



    #define Queur Size 100  //应根据具体情况定义该值



    typedef char Queue DataType; //DataType的类型依赖于具体的应用



    typedef Sturet{              //头指针,队非空时指向队头元素



          int front;             //尾指针,队非空时指向队尾元素的下一位置



          int rear;              //计数器,记录队中元素总数



          DataType data[QueueSize]



    }CirQueue;



 



(4.5.3)循环队列的基本运算



  用第三种方法,循环队列的六种基本运算:



  ①置队空



     void InitQueue(CirQueue *Q)



     {



             Q->front=Q->rear=0;



             Q->count=0;    //计数器置0



      }



 



  ②判队空



      int QueueEmpty(CirQueue *Q)



      {



           return Q->count==0; //队列无元素为空



       }



  ③判队满



int QueueFull(CirQueue *Q)



       {



           return Q->count==QueueSize; //队中元素个数等于QueueSize时队满



        }



  ④入队



void EnQueue(CirQueuq *Q,DataType x)



        {



           if(QueueFull((Q))                  



                  Error("Queue overflow");    //队满上溢



           Q->count ++;                       //队列元素个数加1



           Q->data[Q->rear]=x;                //新元素插入队尾



           Q->rear=(Q->rear+1)%QueueSize;     //循环意义下将尾指针加1



  ⑤出队



DataType DeQueue(CirQueue *Q)



         {



             DataType temp;



             if(QueueEmpty((Q))



                  Error("Queueunderflow");    //队空下溢



             temp=Q->data[Q->front];



             Q->count--;                       //队列元素个数减1



             Q->front=(Q->front+1)&QueueSize;  //循环意义下的头指针加1



             return temp;



          }



             



  ⑥取队头元素



DataType QueueFront(CirQueue *Q)



           {



               if(QueueEmpty(Q))



                   Error("Queue ifempty.");



               return Q->data[Q->front];



           }



           



----------------------



(5)链式队的基本操作:LinkQueue



 



        (一)不带有头节点的链表:(不推荐此种)



        (5.1)链式队列图解:



队列总结_legend_队列_03



        (5.2)链式列队讲解:



        通常链式队列用不带头节点的链表表示。



 



        节点类型定义:



 



        structqNodeType{



        ElemTypedata;



        structqNodeType* next;



        }QNode;



 



        存放队头,队尾指针的链队类型:



 



        typedefstruct{



        QNode* front;



        QNode* rear;



        }LiQueue;



 



 



        (5.3)链式队列要素:



 



                  (5.3.1)初始化:



                  front=NULL;



                  rear=NULL;



                  (5.3.2)队空:front==NULL&& rear==NULL



                  (5.3.3)队满:不存在



                  (5.3.4)元素elem进队:



 



                  建立一个数据域为elem的新节点pNewNode;将pNewNode插入到队尾,并更新rear.



                  即:Q.rear->next=pNewNode;Q.rear=pNewNode;



                  注:初始时rear==NULL;



                  所以需要:



                  if(NULL==rear)         {front=rear=pNewNode;}



                  else{



                  rear->next=pNewNode;rear=pNewNode;/*更新rear*/



                  }



 



                  (5.3.5)非空出队:



                  QNode* pnode=Q.front->next;



                  ElemTypeelem=pnode->data;/*获取第一个节点的数据域*/



                  Q.front->next=pnode->next;



                  deletepnode;



 



                  注:若只有一个节点且出栈:



                  则以上语句不能保证rear=NULL;



                  所以: QNode *pnode=Q.front->next;



                  ElemTypeelem=pnode->data;/*获取第一个节点的数据域*/



                  Q.front->next=pnode->next;



                  if(pnode->next==NULL){rear=front=NULL;}/*保证只有一个节点,出队后,队空成立*/



                  deletepnode;



        -------------------------------



        (二)方法二:(推荐)



 



        (5.1)队列的基本操作:



 



                  (5.1.1)初始化:QNode*pnode=new QNode; front=rear=pnode;/*避免了初次插入时的rear=NULL的判断*/



                  (5.1.2)队空:front==rear;



                  (5.1.3)元素ele进队:rear->next=pNewNode;rear=pNewNode;



                  (5.1.4)非空出队:



                                    QNode*firstNode=front->next;



                                    ElemTypeelem=firstNode->data;



                                    front->next=firstNode->next;



                                    if(firstNode->next==NULL)



                                    {



                                    rear=front;/*当只有一个节点并且出队,保证队空*/


                                    /*因为如果不更新rear的话,rear是出队前的最后一个节点的指针,即第一个节点的指针。出队前front->next=rear;(只有一个节点时);



                                    出队后:front!=rear,显然不符合队空的定义。



                                    */



                                    }



                                    deletepnode;



 



                  (5.1.5)获取队头:



                           if(front!=rear)return front->next->data;



 



        (5.2)代码实现:




 



 



(6)双端队列:



双端队列的基本实现:





双端队列的应用:滑动窗口



 



 



(7)队列的扩展操作:



        (6.1)迷宫之最短路径问题:



        (6.2)O(1)时间内求队列中最小值:(优先队列)



        (6.3)广度优先搜索:BFS



 

标签:总结,4.3,队列,next,出队,front,legend,rear
From: https://blog.51cto.com/u_15911260/5951030

相关文章

  • django总结
    内容导航django路由层内容详细django路由层1.路由匹配django2.X及以上path第一个参数些什么就匹配什么django1.X第一个参数是正则表达式无论匹配什么版本dja......
  • Nginx入门--学习总结
    Nginx入门核心功能:反向代理、负载均衡、动静分离nginx的安装、启动nginx常用命令,进入/usr/local/nginx/sbin./nginx--启动./nginx-sstop--停止nginx./ng......
  • 架构设计(六):引入消息队列
    架构设计(六):引入消息队列作者:Grey原文地址:博客园:架构设计(六):引入消息队列CSDN:架构设计(六):引入消息队列消息队列是一个支持持久化的组件,数据存储在内存中,支持异步通信。它......
  • 十二周总结
    十二周总结django请求生命周期流程图Django路由层1.路由匹配django1.X版本路由的第一个参数是正则表达式django2.X及以上版本的则是path写什么就匹配什么......
  • cpp优先队列(priority_queue)
    优先队列的概念在优先队列中,队列中的每个元素都与某个优先级相关联,但是优先级在队列数据结构中不存在。优先队列中具有最高优先级的元素将被首先删除,而队列遵循FIFO(......
  • 第九周学习总结
    本周重温了ECCV2020上NeRF提出的论文,全文详细阅读了两遍,对其原理大概做到了心中有数:首先NeRF是在基于渲染角度提出的一个新的视图合成的办法,而所谓渲染,是将三维......
  • 周总结
    可视化界面之数据增删改查针对数据对象主键字段的获取可以使用更加方便的obj.pk获取在模型类中定义双下str方法可以在数据对象被执行打印操作的时候方便的查看'''for......
  • 【博学谷学习记录】超强总结,用心分享|狂野架构常见编程规约
    编程规约方法参数类型必须一致,不要出现自动装箱拆箱操作2.1.1.1反例这种操作很容易产生难以排查的NPE异常/***反例*容易出现空指针异常,如果参数为null就会......
  • 第十二周总结
    目录django之路由层django请求生命流程路由匹配转换器正则匹配反向解析路由分发名称空间django视图层视图层之不会三板斧JsonResponse对象视图层之request对象获取文件视图......
  • 冒泡排序相关知识总结
    轮数表示冒泡排序外层循环的次数,次数表示交换次数。设排列为\(w\),冒泡排序的轮数为\(\max_{i=1}^{n}(i-w_i)\).因为如果\(i>w_i\),那么这个数每一轮会向目的地......