• 算法与数据结构 --- 队列的表示和操作的实现


    第一部分 --- 队列顺序表示和实现(1,2,3)

     1.我们只能够在队尾插入新元素,在队头删除元素

     

     1.任何需要排队的情况都需要用到队列数据结构

    1.QElemType 这个类型和队列中要存储的元素的类型一致

    2.队列结构体中两个整型变量(front和rear),这两个整型变量分别是队头的数组下标和队尾的数组下标(用顺序表的方式来实现队列的时候)

    1.rear指针始终指向可以入队的空间

    2.出队时我们要将被出队的元素用一个数据变量保存

    1.当front = 0 的时候,rear = MAXQSIZE 时数组中的确没有内存空间了,此时插入元素到队列中时出现的溢出情况就是真溢出了

    2.当front != 0 ,rear = MAXQSIZE 的时候,数组中仍然有内存空间,此时插入元素到队列中出现的溢出情况为假溢出

     

    1.a%b,如果a

    利用上面这个特性我们就能跟实现循环队列

    2.以front下标为例,每次出队的时候front指针都要上移,出于对空间的利用,我们希望在front下标的值 = MAXQSIZE - 1 的时候,它的下一次上移会使得front下标的值 = 0 而不是 = MAXQSIZE

    (即形成循环队列来解决假溢出问题) --- 实现方式是下面这行代码

    原始的上移就是 Q.front = Q.front +1 ; 以这种上移方式在Q.front = MAXQSIZE - 1的时候再次上移得到的是MAXQSIZE,不符合我们的要求

    而采用新的上移方式:的话,当Q.front = MAXQSIZE - 1的时候 ,它再上移得到的值就是0!,而当小于MAXQSIZE - 1的时候,得到的上移值和原始上移值一样,这样就完美的满足了我们的需求。

     

    1.队满的时候就不能够再入队了,且空一个元素的话,队满时就会有一个性质:

    我们可以根据这个性质来判断是否队满(在空一个元素的前提下,这个性质和队满互为充要条件)

     

    1.如果在堆区内存空间分配成功的话就继续操作,分配失败的话就返回内存空间溢出错误

    (注意此处采用的是空一个元素的方式来表示队满!队满时,队中的元素个数 = MAXQSIZE - 1)

    1.循环队列计算队列长度的时候有两种情况:

    第一种是rear下标在front下标上面,此时直接用rear下标减去front下标就能够得到队列中的元素个数了(即队列长度)

    第二种则是rear下标在front下标下面(循环队列特点),此时用rear下标减去front下标得到的是一个负值(取这个负值的绝对值就能够得到此时队列中还能够插入多少个元素),此时我们将这个负值和队列容量 MAXQSIZE求和就能够得到队列中的元素个数了

    2.那么问题来了,我们如何把这两种情况统一用一个表达式表示出来呢?

    答案就是这个:

    一.先对rear下标大于front下标的情况进行分析,此时rear - front得到的就是队列中的元素个数,设为X,上面那个表达式就变为(X + MAXQSIZE)%MAXQSIZE , 展开后最终取余的结果依然等于X

    二.接着对rear下标小于front下标的情况进行分析,此时X + MAXQSIZE本身就等于队列中元素的个数,且这两个的和 < MAXQSIZE(因为队列采用空一个元素的方式表示队满),此时表达式取余后的最终结果依然是队列中的元素个数

    1.首先判断是否队满(此处采用的是处于空一个元素的形式下的判断队满的方式),若满了则无法入队,返回error,若没满则正常入队(采用取余移动rear下标保证队列为循环队列)

    1.首先判断队列是否为空(在队列中空一个元素的情况下,rear下标是否等于front下标),若为空无元素可出队返回reeor,若不为空则正常出队(输出元素,同时用取余的方式上移front下标)

    1.第一步依然是判断队列是否为空,为空的话就不存在队头给我们取了,返回error,若不为空则正常返回队头元素值,队列不变(取队尾元素值也同理)


    第二部分 --- 队列的链式表示和实现(4)

    如果不知道队列有多长,我们可以用链表来实现队列(动态分配内存空间,只要空间够,可以一直添加元素)

    1.Qnode(链队列),Lnode(链表),Snode(链栈)

    2.左边那个结构体是在定义链表的结点,右边那个结构体是在定义一个结构体,方便管理链队列的队头指针和队尾指针

    3.链队列具有头结点,且同时具有队头指针(注意链表中的队头指针指向的头结点,相当于头指针,而不是指向首元结点,不过根据链表的特性我们依然可以通过队头指针删除第一个元素 --- 首元结点)和队尾指针(指向尾结点)

     

    1.如果在堆区中出现开辟内存空间失败,那就返回内存溢出错误(OVERFLOW)

    2.开辟好头结点后由于是空链队列,所以头结点的next指针域要设为空指针

    1.当 Q.front 为空指针的时候(Q.front == NULL ),链队列中的所有结点都被释放完毕,循环停止

    2.进行销毁操作的时候除了创建一个新的指针变量来进行销毁外,我们还可以直接用队尾指针来代替新创建的指针来进行销毁

     

     1.首先判断栈队列是否为空,若为空的话就返回ERROR(空链队列没有元素能够出队)

    2.当我们将链队列中除头结点外的的所有结点都出队之后,我们要将队尾指针也指向头结点

     

     

  • 相关阅读:
    java计算机毕业设计弹幕视频网站源码+系统+lw文档+mysql数据库+部署
    融合通信 RDS服务器接口定义1.9
    unittest自动化框架
    Springboot+vue的社区医院管理系统(有报告),Javaee项目,springboot vue前后端分离项目
    直接激光雷达里程计:基于稠密点云的快速定位
    Spring参数校验
    Abbkine通用型免疫荧光工具箱(抗小鼠Dylight 488)方案
    JUC笔记(六) --- 不可变共享模型
    输入一行字符,分别统计出其中英文字母、数字、空格和其他字符的个数。c++
    Linux-命令大全
  • 原文地址:https://blog.csdn.net/qq_51947882/article/details/126883126