目录
一、队列的含义
1.队列的使用
2.队列的结构
二、顺序队列的实现
1.队列的定义
2.队列的初始化
3.清空对列
4.队列是否为空
5.获取队列的长度
6.获取头元素的值
7.入队列
8.出队列
9.遍历队列中的值
10.总代码
11.打印结果
三、链表队列的实现
1.队列的初始化
2.销毁队列
3.清理队列
4.队列是否为空
5.求队列的长度
6.获取头节点的值
7.出队列
8.入队列
9.遍历队列
10.全代码
11.打印测试
一、队列的含义
1.队列的使用
我们在用电脑时有没有经历过,机器有时会处于疑似死机的状态,鼠标点什么似乎都没用,双击任何快捷方式都不动弹。就当你失去耐心,打算关机,突然它就像醒了一样,把你刚才点击的所有操作全部都按顺序执行了一遍。这其实是因为操作系统中的多个程序因需要通过一个通道输出,而按先后次序排队等待造成的。
再比如像移动、联通、电信等客服电话,客服人员与客户相比总是少数,在所有的客服人员都占线的情 况下,客户会被要求等待,直到有某个客服人员空下来,才能让最先等待的客户接通电话。这里也是将 所有当前拨打客服电话的客户进行了排队处理。
2.队列的结构
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出的线性表,简称 FIFO。允许插入的一端称为队尾,允许删 除的一端称为队头。 这里从队列中的定义中,不难看出队列和栈一样也都是一种线性表,也就是说队有顺序队列和链式队两大类。
二、顺序队列的实现
因为顺序对列中,队列中的大小是固定的,在 tail 指针插满后,它会从0开始继续插入元素,所以说它是环形插入的,因此要考虑三种情况。在实现顺序队列之前,我们先看三张图,分别代表顺序队列的三种情况。
第一种:head 指针 == tail 指针,此时队列中元素为空。

第二种:head 指针 < tail 指针,此时Tail指针还没有到队列尾部。

第三种:head 指针 > tail 指针,此时Tail指针到达队列尾部后,继续从头开始插入

1.队列的定义
主要完成对队列的定义和一些常量的定义。
#include <iostream>
#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct
{
	ElemType data[MAX_SIZE];
	int front;    // 头指针: 用来出栈
	int rear;     // 尾指针: 用来入栈
}SqQueue;2.队列的初始化
以为用的是双指针来代表队列,所以直接等于0就行。
// 初始化队列
Status InitQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}3.清空对列
和队列的初始化一样。
// 清空队列
Status ClearQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}4.队列是否为空
// 队列是否为空
Status QueueEmpty(SqQueue Q)
{
	if (Q.front == Q.rear) return TRUE;
	return FALSE;
}5.获取队列的长度
// 获取队列的长度
int QueueLength(SqQueue Q)
{
	// 需要考虑三种情况
	return (Q.rear - Q.front + MAX_SIZE) % MAX_SIZE;
}
6.获取头元素的值
// 获取头元素的值
Status GetHead(SqQueue Q, ElemType* e)
{
	if (Q.front == Q.rear) return ERROR;
	*e = Q.data[Q.front];
    return OK;
}
7.入队列
// 入队列
Status EnQueue(SqQueue* Q, ElemType e)
{
	// 判断是否满了
	if (((Q->rear + 1) % MAX_SIZE) == MAX_SIZE) return ERROR;
    Q->data[Q->rear] = e;
	Q->rear = (Q->rear + 1) % MAX_SIZE;
	return OK;
}8.出队列
// 出队列
Status DeQueue(SqQueue* Q, ElemType* e)
{
	if (Q->front == Q->rear) return ERROR;
	*e = Q->data[Q->front];
	Q->front = (Q->front + 1) % MAX_SIZE;
	return OK;
}9.遍历队列中的值
// 打印队列中的值
Status QueueTraverse(SqQueue Q)
{
	int i = Q.front;
	while (i != Q.rear)
	{
		if (i != Q.front) printf("->");
		printf("%d", Q.data[i]);
		i = (i + 1) % MAX_SIZE;
	}
	printf("\n");
	return OK;
}10.总代码
#include <iostream>
#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct
{
	ElemType data[MAX_SIZE];
	int front;    // 头指针: 用来出栈
	int rear;     // 尾指针: 用来入栈
}SqQueue;
// 初始化队列
Status InitQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}
// 清空队列
Status ClearQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}
// 队列是否为空
Status QueueEmpty(SqQueue Q)
{
	if (Q.front == Q.rear) return TRUE;
	return FALSE;
}
// 获取队列的长度
int QueueLength(SqQueue Q)
{
	// 需要考虑三种情况
	return (Q.rear - Q.front + MAX_SIZE) % MAX_SIZE;
}
// 获取头元素的值
Status GetHead(SqQueue Q, ElemType* e)
{
	if (Q.front == Q.rear) return ERROR;
	*e =  Q.data[Q.front];
	return OK;
}
// 入队列
Status EnQueue(SqQueue* Q, ElemType e)
{
	// 判断是否满了
	if (((Q->rear + 1) % MAX_SIZE) == MAX_SIZE) return ERROR;
	Q->data[Q->rear] = e;
	Q->rear = (Q->rear + 1) % MAX_SIZE;
	return OK;
}
// 出队列
Status DeQueue(SqQueue* Q, ElemType* e)
{
	if (Q->front == Q->rear) return ERROR;
	*e = Q->data[Q->front];
	Q->front = (Q->front + 1) % MAX_SIZE;
	return OK;
}
// 打印队列中的值
Status QueueTraverse(SqQueue Q)
{
	int i = Q.front;
	while (i != Q.rear)
	{
		if (i != Q.front) printf("->");
		printf("%d", Q.data[i]);
		i = (i + 1) % MAX_SIZE;
	}
	printf("\n");
	return OK;
}
int main()
{
	Status j;
	int i = 0;
	ElemType d;
	SqQueue Q;
	InitQueue(&Q);
	printf("初始化队列后,队列空否?%u(1:空 0:否)\n", QueueEmpty(Q));
	do
	{
		d = (i++) + 100;
		EnQueue(&Q, d);
	} while (i < MAX_SIZE - 1);
	printf("队列长度为: %d\n", QueueLength(Q));
	printf("现在队列中的元素为: \n");
	QueueTraverse(Q);
	while (QueueLength(Q) > 2)
	{
		DeQueue(&Q, &d);
		printf("删除的元素值为%d\n", d);
	}
	j = GetHead(Q, &d);
	if (j)
		printf("现在队头元素为: %d\n", d);
	ClearQueue(&Q);
	printf("清空队列后, 队列空否?%u(1:空 0:否)\n", QueueEmpty(Q));
	return 0;
}
11.打印结果

三、链表队列的实现
如下图所示,Head 头节点data为 NULL,next 指向 节点值为2的节点。Tail 尾节点就等于值为 5 的节点。

1.队列的初始化
#include <iostream>
#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct QNode
{
	ElemType data;
	QNode* next;
}*QueuePtr;
typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;
Status InitQueue(LinkQueue* Q)
{
	Q->front = (QueuePtr)malloc(sizeof(QNode));
	Q->rear = Q->front;
	if (Q->front == NULL)
	{
		return ERROR;
	}
	Q->front->next = NULL;
	return OK;
}
2.销毁队列
Status DestoryQueue(LinkQueue* Q)
{
	while (Q->front)
	{
		Q->rear = Q->front->next;
		free(Q->front);
		Q->front = Q->rear;
	}
	return OK;
}3.清理队列
Status ClearQueue(LinkQueue* Q)
{
	// 让头节点和尾节点回到初始化的状态
	QueuePtr q, p;
	Q->rear = Q->front;
	p = Q->front->next;
	Q->front->next = NULL;
	while (p) 
	{
		q = p;
		p = p->next;
		free(q);
	}
	return OK;
}4.队列是否为空
Status QueueEmpty(LinkQueue Q)
{
	if (Q.front == Q.rear) return TRUE;
	return FALSE;
}
5.求队列的长度
int QueueLength(LinkQueue Q)
{
	int count = 0;
	QueuePtr p = Q.front;
	while (p != Q.rear && p != NULL)
	{
		p = p->next;
		count++;
	}
	return count;
}6.获取头节点的值
Status GetHead(LinkQueue Q,ElemType* e)
{
	QueuePtr p;
	if (Q.front == Q.rear) return ERROR;
	p = Q.front->next;
	*e = p->data;
	return OK;
}7.出队列
Status DeQueue(LinkQueue* Q,ElemType* e)
{
	if (Q->front == Q->rear) return ERROR;
	QueuePtr temp = Q->front->next;
	*e = temp->data;
	Q->front->next = temp->next;
	// 判断以下: 如果 尾节点 = temp,让头节点与尾节点相等
	if (Q->rear == temp)  Q->rear = Q->front;
	free(temp);
	return OK;
}8.入队列
Status EnQueue(LinkQueue* Q,ElemType e)
{
	QueuePtr temp;
	temp = (QueuePtr)malloc(sizeof(QNode));
	temp->data = e;
	temp->next = NULL;
	Q->rear->next = temp;
	Q->rear = temp;
	return OK;
}9.遍历队列
Status QueueTraverse(LinkQueue Q)
{
	QueuePtr temp = Q.front->next;
	while (temp)
	{
		if (temp != Q.front->next) printf("->");
		printf("%d", temp->data);
		temp = temp->next;
	}
	printf("\n");
	return OK;
}10.全代码
#include <iostream>
#define MAX_SIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct QNode
{
	ElemType data;
	QNode* next;
}*QueuePtr;
typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;
Status InitQueue(LinkQueue* Q)
{
	Q->front = (QueuePtr)malloc(sizeof(QNode));
	Q->rear = Q->front;
	if (Q->front == NULL)
	{
		return ERROR;
	}
	Q->front->next = NULL;
	return OK;
}
Status DestoryQueue(LinkQueue* Q)
{
	while (Q->front)
	{
		Q->rear = Q->front->next;
		free(Q->front);
		Q->front = Q->rear;
	}
	return OK;
}
Status ClearQueue(LinkQueue* Q)
{
	// 让头节点和尾节点回到初始化的状态
	QueuePtr q, p;
	Q->rear = Q->front;
	p = Q->front->next;
	Q->front->next = NULL;
	while (p) 
	{
		q = p;
		p = p->next;
		free(q);
	}
	return OK;
}
Status QueueEmpty(LinkQueue Q)
{
	if (Q.front == Q.rear) return TRUE;
	return FALSE;
}
int QueueLength(LinkQueue Q)
{
	int count = 0;
	QueuePtr p = Q.front;
	while (p != Q.rear && p != NULL)
	{
		p = p->next;
		count++;
	}
	return count;
}
Status GetHead(LinkQueue Q,ElemType* e)
{
	QueuePtr p;
	if (Q.front == Q.rear) return ERROR;
	p = Q.front->next;
	*e = p->data;
	return OK;
}
Status EnQueue(LinkQueue* Q,ElemType e)
{
	QueuePtr temp;
	temp = (QueuePtr)malloc(sizeof(QNode));
	temp->data = e;
	temp->next = NULL;
	Q->rear->next = temp;
	Q->rear = temp;
	return OK;
}
Status DeQueue(LinkQueue* Q,ElemType* e)
{
	if (Q->front == Q->rear) return ERROR;
	QueuePtr temp = Q->front->next;
	*e = temp->data;
	Q->front->next = temp->next;
	// 判断以下: 如果 尾节点 = temp,让头节点与尾节点相等
	if (Q->rear == temp)  Q->rear = Q->front;
	free(temp);
	return OK;
}
Status QueueTraverse(LinkQueue Q)
{
	QueuePtr temp = Q.front->next;
	while (temp)
	{
		if (temp != Q.front->next) printf("->");
		printf("%d", temp->data);
		temp = temp->next;
	}
	printf("\n");
	return OK;
}
int main()
{
	int i;
	ElemType d;
	LinkQueue q;
	i = InitQueue(&q);
	if (i)
		printf("成功地构造了一个空队列!\n");
	printf("是否空队列?%d(1:空 0:否) ", QueueEmpty(q));
	printf("队列的长度为%d\n", QueueLength(q));
	EnQueue(&q, -5);
	EnQueue(&q, 5);
	EnQueue(&q, 10);
	printf("插入 3 个元素(-5,5,10)后,队列的长度为%d\n", QueueLength(q));
	printf("是否空队列?%d(1:空 0:否) ", QueueEmpty(q));
	printf("队列的元素依次为:");
	QueueTraverse(q);
	i = GetHead(q, &d);
	if (i == OK)
		printf("队头元素是:%d\n", d);
	DeQueue(&q, &d);
	printf("删除了队头元素%d\n", d);
	printf("队列的元素依次为:");
	QueueTraverse(q);
	i = GetHead(q, &d);
	if (i == OK)
		printf("新的队头元素是:%d\n", d);
	ClearQueue(&q);
	printf("销毁队列后,q.front=%u q.rear=%u\n", q.front, q.rear);
	return 0;
}
11.打印测试




















