循环队列定义
为了解决上次的假溢出问题我们就再从头开始,也就是头尾相接的循环,这种头尾相接的顺序存储结构称为循环队列
接上次问题将rear改为指向下标为0的位置,若再入两个元素则rear指针和front指针重合,同时指向一个下标,那么空队列时front = rear现在满队列也是,怎么判断是空还是满
1设置一个标志变量flag,当front == rear且flag = 0时队列为空,当front == rear且flag=1时未满
2当队列为空时,条件是front == rear,当队列满时,修改其他条件,保留一个元素空间就是说队列满时,数组中还有一个空闲单元时就认为队列满了
第二种方法由于rear可能比front大也可能小,所以他们只差一个位置时就是满的,但也可能是相差一圈。假设队列最大尺寸为queuesize,那么队列满的时候条件是(rear+1)%queuesize == front(取模%的目的是整合rear与front大小为一个问题)
当rear >front时,队列长度为rear - front,当rear < front时,长度为rear - front + queuesize 所以通用的计算队列长度公式是:(rear - front + queuesize)%queuesize
队列的链式存储结构
单是顺序存储就算是循环队列也会面临数组溢出的问题,所以还是需要不用担心队列长度的链式存储结构
队列的链式存储结构,就是线性表的单链表,只是只能尾进头出,简称为链队列,将队头指针指向链队列的头结点,队尾指针指向终点
队列的链式存储结构的出队和入队操作:入队:在链表尾部插入结点,出队:头结点的后继结点出队,将头结点的后继改为它后面的结点,若链表除头结点外只剩一个元素时,则rear指向头结点
对于循环队列与链队列可以从两方面考虑,时间复杂度均为O(1),空间上来看,循环队列必须有一个固定的长度,所以有空间浪费的问题,链队列更灵活一些,总的来说在可以确定队列长度最大值的情况下,建议使用循环队列反之则用链队列
总结
栈和队列都是特殊的线性表,只是在插入和删除的操作上进行了限定
栈:限定仅在表尾进行插入和删除操作的线性表
队列:只允许在一端进行插入操作,在另一端进行删除操作的线性表
它们都可以用线性表的顺序存储结构实现,对于栈来说,如果是两个相同数据类型的栈,可以用数组的两端做栈底让两个栈共享数据,但两个栈最好是此消彼长的相互关系。对于队列,为了防止数组插入和删除是需要移动数据,所以引入循环队列,让
队头和队尾可以在数组中循环变化。两者也都可以通过链式存储结构实现