队列

1. 队列概念和结构

队列与栈类似是一种特殊的线性表, 其只允许在一端删除数据, 在另外一端插入数据

删除数据的一端叫做队头, 插入数据的一端叫做队尾

删除与插入操作在队列中, 叫做出队和入队, 如下图

其次, 队列中的所有数据都遵守先进先出原则

比如要将1移出队列, 必须首先将数据0先出队列, 才能将数据1出队

 

2. 队列的实现

下图是实现队列的结构, 其中QueNode链表结构用来存储数据和记录数据之间的次序

Queue结构作为整体用来实现队列, head指向队头 (链表结构的第一个节点), tail指向队尾(最后一个节点), size记录队列中的数据个数

下面具体实现

 

队列结构及接口

typedef int QueDataType;
typedef struct QueNode
{
	QueDataType data;
	struct QueNode* next;
}QueNode;

typedef struct Queue
{
	QueNode* head;
	QueNode* tail;
	int size;
}Queue;

// 初始化队列
void QueInit(Queue* pq);
// 销毁队列
void QueDestroy(Queue* pq);
// 入队
void QuePush(Queue* pq, QueDataType x);
// 出队
void QuePop(Queue* pq);
// 计算队列中数据个数
int QueSize(Queue* pq);
// 判空
bool isQueEmpty(Queue* pq);
// 取队头数据
QueDataType QueFront(Queue* pq);
// 取队尾数据
QueDataType QueBack(Queue* pq);

初始化队列

// 初始化队列
void QueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

入队

// 入队
void QuePush(Queue* pq, QueDataType x)
{
	assert(pq);
	QueNode* newnode = (QueNode*)malloc(sizeof(QueNode));
	if (NULL == newnode)
	{
		perror("QuePush::malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;

	if (NULL == pq->head)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

出队

// 出队
void QuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	if (NULL == pq->head->next)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}

计算队中数据个数

// 计算队列中数据个数
int QueSize(Queue* pq)
{
	return pq->size;
}

 

判断队列是否为空

// 判空
bool isQueEmpty(Queue* pq)
{
	return pq->size == 0;
}

 

取队头/尾数据

// 取队头数据
QueDataType QueFront(Queue* pq)
{
	assert(pq);
	assert(!isQueEmpty(pq));
	return pq->head->data;
}
// 取队尾数据
QueDataType QueBack(Queue* pq)
{
	assert(pq);
	assert(!isQueEmpty(pq));
	return pq->tail->data;
}

 

销毁队列 

// 销毁队列
void QueDestroy(Queue* pq)
{
	assert(pq);
	QueNode* cur = pq->head;
	while (cur)
	{
		QueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

完整代码

queue.h
 #include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

typedef int QueDataType;

typedef struct QueNode
{
	QueDataType data;
	struct QueNode* next;
}QueNode;

typedef struct Queue
{
	QueNode* head;
	QueNode* tail;
	int size;
}Queue;

// 初始化队列
void QueInit(Queue* pq);
// 销毁队列
void QueDestroy(Queue* pq);
// 入队
void QuePush(Queue* pq, QueDataType x);
// 出队
void QuePop(Queue* pq);
// 计算队列中数据个数
int QueSize(Queue* pq);
// 判空
bool isQueEmpty(Queue* pq);
// 取队头数据
QueDataType QueFront(Queue* pq);
// 取队尾数据
QueDataType QueBack(Queue* pq);
queue.c
 #include "queue.h"

// 初始化队列
void QueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
// 销毁队列
void QueDestroy(Queue* pq)
{
	assert(pq);
	QueNode* cur = pq->head;
	while (cur)
	{
		QueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
// 入队
void QuePush(Queue* pq, QueDataType x)
{
	assert(pq);
	QueNode* newnode = (QueNode*)malloc(sizeof(QueNode));
	if (NULL == newnode)
	{
		perror("QuePush::malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;

	if (NULL == pq->head)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}
// 出队
void QuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	if (NULL == pq->head->next)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}
// 计算队列中数据个数
int QueSize(Queue* pq)
{
	return pq->size;
}
// 判空
bool isQueEmpty(Queue* pq)
{
	return pq->size == 0;
}
// 取队头数据
QueDataType QueFront(Queue* pq)
{
	assert(pq);
	assert(!isQueEmpty(pq));
	return pq->head->data;
}
// 取队尾数据
QueDataType QueBack(Queue* pq)
{
	assert(pq);
	assert(!isQueEmpty(pq));
	return pq->tail->data;
}
test.c
 #include "queue.h"
int main()
{
	Queue que;
	QueInit(&que);
	QuePush(&que, 1);
	QuePush(&que, 2);
	QuePush(&que, 3);
	QuePush(&que, 4);
	QuePush(&que, 5);
	while (!isQueEmpty(&que))
	{
		printf("%d ", QueFront(&que));
		QuePop(&que);
	}
	QueDestroy(&que);
}

 

posted @ 2023-04-12 08:42  许木101  阅读(82)  评论(0)    收藏  举报