此条目页的主題是程式設計上的意義。隊列軍事上的意義，請見「**軍事組織**」。
  **提示**：此条目页的主题不是**排隊**。 

**佇列**，又稱為（queue），计算机科學中的一種抽象資料型別，是先进先出（FIFO, First-In-First-Out）的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端（称为*rear*）进行插入操作，在前端（称为*front*）进行删除操作。

队列的操作方式和堆栈类似，唯一的区别在于队列只允许新数据在后端进行添加。

单链队列
----

单链队列使用链表作为基本数据结构，所以不存在伪溢出的问题，队列长度也没有限制。但插入和读取的时间代价较高

#### 存储结构

```
/\* c3-2.h 单链队列－－队列的链式存储结构 \*/
typedef struct QNode
{
 QElemType data;
 struct QNode \*next;
}QNode,\*QueuePtr;

typedef struct
{
 QueuePtr front,rear; /\* 队头、队尾指针 \*/
}LinkQueue;

```

#### 基本操作

```
/\* bo3-2.c 链队列(存储结构由c3-2.h定义)的基本操作(9个) \*/
void InitQueue(LinkQueue \*Q)
{ /\* 构造一个空队列Q \*/
 (\*Q).front=(\*Q).rear=(QueuePtr)malloc(sizeof(QNode));
 if(!(\*Q).front)
 exit(OVERFLOW);
 (\*Q).front->next=NULL;
}

void DestroyQueue(LinkQueue \*Q)
{ /\* 销毁队列Q(无论空否均可) \*/
 while((\*Q).front)
 {
 (\*Q).rear=(\*Q).front->next;
 free((\*Q).front);
 (\*Q).front=(\*Q).rear;
 }
}

void ClearQueue(LinkQueue \*Q)
{ /\* 将Q清为空队列 \*/
 QueuePtr p,q;
 (\*Q).rear=(\*Q).front;
 p=(\*Q).front->next;
 (\*Q).front->next=NULL;
 while(p)
 {
 q=p;
 p=p->next;
 free(q);
 }
}

Status QueueEmpty(LinkQueue Q)
{ /\* 若Q为空队列，则返回TRUE，否则返回FALSE \*/
 if(Q.front->next==NULL)
 return TRUE;
 else
 return FALSE;
}

int QueueLength(LinkQueue Q)
{ /\* 求队列的长度 \*/
 int i=0;
 QueuePtr p;
 p=Q.front;
 while(Q.rear!=p)
 {
 i++;
 p=p->next;
 }
 return i;
}

Status GetHead\_Q(LinkQueue Q,QElemType \*e) /\* 避免与bo2-6.c重名 \*/
{ /\* 若队列不空，则用e返回Q的队头元素，并返回OK，否则返回ERROR \*/
 QueuePtr p;
 if(Q.front==Q.rear)
 return ERROR;
 p=Q.front->next;
 \*e=p->data;
 return OK;
}

void EnQueue(LinkQueue \*Q,QElemType e)
{ /\* 插入元素e为Q的新的队尾元素 \*/
 QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
 if(!p) /\* 存储分配失败 \*/
 exit(OVERFLOW);
 p->data=e;
 p->next=NULL;
 (\*Q).rear->next=p;
 (\*Q).rear=p;
}

Status DeQueue(LinkQueue \*Q,QElemType \*e)
{ /\* 若队列不空，删除Q的队头元素，用e返回其值，并返回OK，否则返回ERROR \*/
 QueuePtr p;
 if((\*Q).front==(\*Q).rear)
 return ERROR;
 p=(\*Q).front->next;
 \*e=p->data;
 (\*Q).front->next=p->next;
 if((\*Q).rear==p)
 (\*Q).rear=(\*Q).front;
 free(p);
 return OK;
}

void QueueTraverse(LinkQueue Q,void(\*vi)(QElemType))
{ /\* 从队头到队尾依次对队列Q中每个元素调用函数vi() \*/
 QueuePtr p;
 p=Q.front->next;
 while(p)
 {
 vi(p->data);
 p=p->next;
 }
 printf("\n");
}

```

循环队列
----

循环队列可以更简单防止伪溢出的发生，但队列大小是固定的。

```
// 队列的顺序存储结构(循环队列)
#define MAX\_QSIZE 5 // 最大队列长度+1
typedef struct {
 int \*base; // 初始化的动态分配存储空间
 int front; // 头指针，若队列不空，指向队列头元素
 int rear; // 尾指针，若队列不空，指向队列尾元素的下一个位置
} SqQueue;

// 构造一个空队列Q
SqQueue\* Q\_Init() {
 SqQueue \*Q = (SqQueue\*)malloc(sizeof(SqQueue));
 // 存储分配失败
 if (!Q){
 exit(OVERFLOW);
 }
 Q->base = (int \*)malloc(MAX\_QSIZE \* sizeof(int));
 // 存储分配失败
 if (!Q->base){
 exit(OVERFLOW);
 }
 Q->front = Q->rear = 0;
 return Q;
}

// 销毁队列Q，Q不再存在
void Q\_Destroy(SqQueue \*Q) {
 if (Q->base)
 free(Q->base);
 Q->base = NULL;
 Q->front = Q->rear = 0;
 free(Q);
}

// 将Q清为空队列
void Q\_Clear(SqQueue \*Q) {
 Q->front = Q->rear = 0;
}

// 若队列Q为空队列，则返回1；否则返回-1
int Q\_Empty(SqQueue Q) {
 if (Q.front == Q.rear) // 队列空的标志
 return 1;
 else
 return -1;
}

// 返回Q的元素个数，即队列的长度
int Q\_Length(SqQueue Q) {
 return (Q.rear - Q.front + MAX\_QSIZE) % MAX\_QSIZE;
}

// 若队列不空，则用e返回Q的队头元素，并返回OK；否则返回ERROR
int Q\_GetHead(SqQueue Q, int &e) {
 if (Q.front == Q.rear) // 队列空
 return -1;
 e = Q.base[Q.front];
 return 1;
}

// 打印队列中的内容
void Q\_Print(SqQueue Q) {
 int p = Q.front;
 while (Q.rear != p) {
 cout << Q.base[p] << endl;
 p = (p + 1) % MAX\_QSIZE;
 }
}

// 插入元素e为Q的新的队尾元素
int Q\_Put(SqQueue \*Q, int e) {
 if ((Q->rear + 1) % MAX\_QSIZE == Q->front) // 队列满
 return -1;
 Q->base[Q->rear] = e;
 Q->rear = (Q->rear + 1) % MAX\_QSIZE;
 return 1;
}

// 若队列不空，则删除Q的队头元素，用e返回其值，并返回1；否则返回-1
int Q\_Poll(SqQueue \*Q, int &e) {
 if (Q->front == Q->rear) // 队列空
 return -1;
 e = Q->base[Q->front];
 Q->front = (Q->front + 1) % MAX\_QSIZE;
 return 1;
}

```

陣列佇列
----

```
#define MAX\_QSIZE 10 // 最大队列长度+1
// 阵列队列的存储结构
struct Queue {
 int Array[MAX\_QSIZE]; // 阵列空间大小
 int front; // 队头
 int rear; // 队尾
 int length; // 队列长度
};

// 构造一个空队列Q
Queue\* Q\_Init() {
 Queue \*Q = (Queue\*)malloc(sizeof(Queue));
 if (!Q){
 // 存储分配失败
 exit(OVERFLOW);
 }
 //初始化
 Q->front = Q->rear = Q->length = 0;
 return Q;
}

// 将Q清为空队列
void Q\_Clear(Queue \*Q) {
 //清除头尾下标和长度
 Q->front = Q->rear = Q->length = 0;
}

// 入列
int Q\_Put(Queue \*Q, int x) {
 //如果当前元素数量等于最大数量 返回 -1
 if (Q->rear + 1 == MAX\_QSIZE) {
 return -1;
 }
 Q->Array[Q->rear] = x;
 Q->rear = Q->rear + 1;
 //length + 1
 Q->length = Q->length + 1;
 return 1;
}

// 出列
int Q\_Poll(Queue \*Q) {
 //如果当前元素数量等于最大数量 返回 -1
 if (Q->front + 1 == MAX\_QSIZE)
 return -1;
 int x = Q->Array[Q->front];
 Q->front = Q->front + 1;
 // 移出后減少1
 Q->length = Q->length - 1;
 return x;
}

```

参考文献
----

1. ↑   高一凡.  2004年10月第2版. 西安: 西安电子科技大学出版社. ISBN 9787560611761 （中文）.

参见
--

* 堆栈
* 链表
* 数组
* 数据结构

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
数据结构 |
| --- |
|  |
| 类型 | 
* 集合
* 容器

 |
|  |
| 抽象类型 | 
* 关联数组
	+ 多重关连数组（英语：）
* 串列
	+ 前向串列
* 堆栈
* 队列
	+ 双端队列
* 优先队列
	+ 双端优先队列
* 集合
	+ 多重集
	+ 併查集
* 可持久化数据结构
	+ 线段树

 |
|  |
| 数组 | 
* 字串
* 位数组
* 环形缓冲器
* 动态数组
* 哈希表
* 哈希数组树（英语：）
* 稀疏矩阵

 |
|  |
| 链（英语：） | 
* 关联表（英语：）
* 链表
* 跳跃列表
* 松散链表（英语：）
* 异或链表

 |
|  |
| 树 | 
* 线段树
* 自平衡二叉查找树
* B树
* 二叉树
	+ AA树
	+ AVL树
	+ 红黑树
	+ 平衡树
	+ 伸展树
	+ 二叉查找树
* 堆
	+ 二叉堆
	+ 左偏树
	+ 二项堆
	+ 斐波那契堆
* R树
	+ R\*树
	+ R+树
	+ 希爾伯特R树（英语：）
* 希尔伯特前缀树
	+ 哈希树

 |
|  |
| 图 | 
* 有向图
* 有向无环图
* 二元决策图
* 无向图
* 确定性非循环有限自动机（英语：）

 |
|  |
| 数据结构术语 |

 |