版权声明:转载请附上文章地址https://blog.csdn.net/qq_42672839

1.队列的概念 
只允许在一端插入数据操作,在另一端进行删除数据操作的特殊线性表;进行插入操作的一端称为队尾(入队列),进行删除操作的一端称为队头(出队列);队列具有先进先出(FIFO)的特性。

顺序存储就是用数组实现,比如有一个n个元素的队列,数组下标0的一端是队头,入队操作就是通过数组下标一个个顺序追加,不需要移动元素,但是如果删除队头元素,后面的元素就要往前移动,对应的时间复杂度就是O(n),性能自然不高。

2.队列的API

jdk1.5中的阻塞队列的操作如下:

add        增加一个元索                     如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove   移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常
element  返回队列头部的元素             如果队列为空,则抛出一个NoSuchElementException异常
offer       添加一个元素并返回true       如果队列已满,则返回false
poll         移除并返问队列头部的元素    如果队列为空,则返回null
peek       返回队列头部的元素             如果队列为空,则返回null
put         添加一个元素                      如果队列满,则阻塞
take        移除并返回队列头部的元素     如果队列为空,则阻塞

 

3.队列的逻辑

3.1 正常的一个顺序队列:

数据结构(三) 队列

队列的特性:先进先出,进入队列从左边进入,从右边出队列,所以A先进也是A先出

3.2 循环队列

循环公式 tail=(tail+1)%array.Length;

什么是循环队列呢?就是有两个指针,front指向队头,rear指向对尾元素的下一个位置,元素出队时front往后移动,如果到了对尾则转到头部,同理入队时rear后移,如果到了对尾则转到头部,这样通过下标front出队时,就不需要移动元素了。

数据结构(三) 队列

队列为空时,front和rear相等,那队列什么时候判断为满呢?按照循环操作rear依次后移,然后再从头开始,也是出现rear和front相等时,队列满。这样跟队列空的情况就相同了,为了区分这种情况,规定数组还有一个空闲单元时,就表示队列已满,因为rear 可能在front后面,也可能循环到front前面,所以队列满的条件就变成了(rear+1)%maxsize = front ,同时队列元素个数的计算就是(rear -front+maxsize)%maxsize。

队列的链式表示和实现(简称为“链队列”)

队列的链式存储是在链表的基础上,按照“先进先出”的原则操作数据元素。

例如,将队列(A,B,C,D,E)依次入队,然后再依次出队。

代码实现:(C语言)

#include <stdio.h>
#include <stdlib.h>

typedef struct QNode
{
    int data;
    struct QNode *next;
}QNode;

QNode *initQueue()
{
    QNode *queue = (QNode*)malloc(sizeof(QNode));
    queue->next = NULL;
    return queue;
}

QNode *enQueue(QNode *rear, int data)
{
    QNode *enElem = (QNode*)malloc(sizeof(QNode));
    enElem->data = data;
    enElem->next = NULL;
    //使用尾插法向链队列中添加数据元素
    rear->next = enElem;
    rear = enElem;
    return rear;
}

void DeQueue(QNode *front, QNode *rear)
{
    if (front->next == NULL) 
   {
        printf("队列为空");
        return ;
    }
    QNode *p = front->next;
    printf("%s", p->data);
    front->next = p->next;
    if (rear == p) 
   {
        rear = front;
    }
    free(p);
}

int main() 
{
    QNode *queue, *front, *rear;
    queue = front = rear = initQueue();  //创建头结点
    //向链队列中添加结点,使用尾插法添加的同时,队尾指针需要指向链表的最后一个元素
    rear = enQueue(rear, A);
    rear = enQueue(rear, B);
    rear = enQueue(rear, C);
    rear = enQueue(rear, D);
    rear = enQueue(rear, E);
    //入队完成,所有数据元素开始出队列
    DeQueue(front, rear);
    DeQueue(front, rear);
    DeQueue(front, rear);
    DeQueue(front, rear);
    DeQueue(front, rear);
    DeQueue(front, rear);
    
  return 0;
}

运行结果:


ABCDE队列为空

相关文章: