数据结构之队列

目录

一、队列的含义

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.打印测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大卫的纯爱战士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值