C语言数据结构(5)——队列


在这里插入图片描述

1.队列基本概念

队列和栈一样,是对于数据的存和取有严格要求的线性存储结构。
队列与栈的区别在于,队列的两端都是开口,要求数据只能从一段进,从另一端出。
队列存储结构
队头——出数据的一端
队尾——进数据的一端
队列中的数据遵循先进先出(FIFO,First In First Out)的原则,如图,元素1首先进队,那1也将率先出队,元素3最后进队,也将最后出队。


2.队列的实现

由于线性表即可实现队的结构,故单链表和顺序表皆可。但是顺序表在实现队列出队后,将剩余元素前移效率很低(除非使用循环队列,但存在上限)。本文将实现链表结构的队列。
队列的基本操作有

  • 初始化队列
void QueueInit(Queue* pq);
  • 检测队列是否为空
bool QueueEmpty(Queue* pq);
  • 队尾处入队
void QueuePush(Queue* pq, QDataType x);
  • 队头处出队
QDataType QueuePop(Queue* pq);
  • 获取队头处元素
QDataType QueueFront(Queue* pq);
  • 获取队尾元素
QDataType QueueBack(Queue* pq);
  • 获取队列中有效元素的个数
int QueueSize(Queue* pq);
  • 销毁队列
void QueueDestroy(Queue* pq);

2.1 基本数据类型

typedef int QDataType;

//结点链式结构
typedef struct QNode
{
	QDataType data;
	struct QNode* next;
}QNode;

//队列结构
typedef struct Queue
{
	QNode* head;//队头:出队
	QNode* tail;//队尾:入队
}Queue;

2.1 初始化队列

void QueueInit(Queue* pq)
{
	assert(pq);

	pq->head = NULL;
	pq->tail = NULL;
}

2.2 检测队列是否为空

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL;
}

2.3 队尾处入队

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	//创建结点
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	assert(newnode);
	newnode->data = x;
	newnode->next = NULL;

	//接入到队尾
	//如果head为NULL
	if (pq->head == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

2.4 队头处出队

QDataType QueuePop(Queue* pq)
{
	assert(pq);
	//队列不为空
	assert(!QueueEmpty(pq));

	//记录队列第二个元素的位置
	QNode* second_place=pq->head->next;
	free(pq->head);
	pq->head = second_place;

	//如果删除的是最后一个元素,记得把tail置为NULL,否则tail将会成为野指针,指向已被free的空间
	if (pq->head == NULL)
	{
		pq->tail = NULL;
	}
}

2.5 获取队头处元素

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

2.6 获取队尾元素

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

2.7 获取队列中有效元素的个数

int QueueSize(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	int count = 0;
	while (cur)
	{
		QNode* post = cur->next;
		count++;
		cur = post;
	}
	return count;
}

2.8 销毁队列

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* post = cur->next;
		free(cur);
		cur = post;
	}

	pq->head = pq->tail = NULL;
}

3.功能展示

#include "Queue.h"

void TestQueue1()
{
	Queue q;
	QueueInit(&q);
	//入队
	printf("入队1 2 3 4\n");
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);

	//获取队列个数
	printf("元素个数:%d\n", QueueSize(&q));

	//QueueDestroy(&q);
	//获取队头元素
	printf("队头元素=%d\n", QueueFront(&q));
	 
	//出队
	printf("出队\n");
	QueuePop(&q);
	printf("队头元素=%d\n", QueueFront(&q));
	//获取队尾元素
	printf("队尾元素=%d\n", QueueBack(&q));

}

int main()
{
	TestQueue1();
	return 0;
}

在这里插入图片描述


青山不改 绿水长流
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值