看到一个很棒的环形数组队列实现方法,转载过来。
原网址:https://blog.csdn.net/xuanwolanxue/article/details/68925446
话不多说,上重点:
这里主要指的是队列的入队(enqueue)与出队(dequeue),对于链式队列来说,其入队和出队也就是链表的尾部插入与移除头部节点,这里就不多说,主要说一下以数组实现的循环链表的具体实现(其中head和tail都是表示数组的下标)。
入队: 如上面的循环队列示意图,入队操作,需要先判断tail节点的下一个位置是否是head,如果是就表示队列已满,无法入队,如果不是,那就可以入队,也即是将元素放入tail的下一个位置,最后将tail加一(也就是指向最终的尾元素),其伪代码如下:
/** 取余保证,当tail = size - 1 时,转回到0 */
int tail = (queue->tail + 1) % queue->size;
if (tail != queue->head)
{ /** 此处这样写,是因为正常情况下,非满的情况多于满了的情况,这样写可以稍微的加快点执行速度 */
queue->elems[queue->tail] = elem;
queue->tail = tail;
}
else /** 此时队列已满 */
{
printf("the queue is full!");
}
出队: 先判断 tail 和head是否相等,如果相等,就比较队列已空,无元素可出,不等则表示非空。此时需要取出head对于位置的元素,然后将head加1(当然,为了能够在head 增加到数组尾部时能够转回到首部,那么这里其实需要 将head加1与队列的size取余再赋值给head),其伪代码如下:
elem_type elem = elem_null; /** 初始化元素 */
if(queue->tail != queue->head) /** 判断队列不为空 */
{/**这样写的作用与上一段伪代码的作用是一样的 */
elem = queue->elems[queue->head];
/** 取余保证,当head= size - 1 时,转回到0 */
queue->head = (queue->head+1) % queue->size;
}
else /** 此时队列已空 */
{
printf("the queue is empty \n");
}
return elem;