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

第一部分 --- 队列顺序表示和实现(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<b的话,则a%b得到的余数是a本身,如果a == b,则a%b得到的余数等于0

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

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.当我们将链队列中除头结点外的的所有结点都出队之后,我们要将队尾指针也指向头结点

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值