[数据结构] 队列(Queue)的认识和基本算法

队列的概念介绍:

队列就像是一群排队等待进入某个地方的人群,每个人都按照先来后到的顺序排队等候。在队列中,第一个进入队列的人最先被服务,而最后一个进入队列的人最后才能被服务。队列的特点就是先进先出,简称FIFO(First In, First Out)。

比如在购物超市结账时的场景,顾客们排成一条长龙,第一个顾客先进入结账台,依次往后,最后一个才能被服务。这种排队方式就是队列的典型应用。以及医院和其他场景的一些叫号机也是同样的原理,这样确保了排队的公平性,先进的就一定先出,队列有头和尾,不像栈那样可能会有多出出栈的顺序。

下面是一张方便理解的示意图:(图片是博主上网随便找的,如有侵权及时联系修改)

代码实现队列的基本算法:

注:

数据结构没有明确规定实现队列的代码就应该怎么这么样,下面是仅供参考的代码,只要能实现同样的功能即可。

基本算法的几种算是约定俗成的,根据实际需要而产生的,基本上与之前的顺序表,链表,栈很类似。

考虑到队伍的头删和尾插,在选择上显然更多时候使用链表会比数组更合适。

头文件Queue.h:

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

typedef int QDataType;
//链表/队列的节点
typedef struct QueueNode {
	int val;
	struct QueueNode* next;
}QNode;
//队列
typedef struct Queue {
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;

void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);

//入队列
void QueuePush(Queue* pq, QDataType x);
//出队列
void QueuePop(Queue* pq);

QDataType QueueFrond(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);

源文件Queue.c:

#include"Queue.h"

void QueueInit(Queue* pq) {
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void QueueDestroy(Queue* pq) {
	assert(pq);
	//保留头结点
	QNode* cur = pq->phead;
	//循环释放队列的每个节点
	while (cur) {
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	//重置队列数据
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

//入队列
void QueuePush(Queue* pq, QDataType x) {
	assert(pq);
	//创建一个新节点
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL) {
		perror("malloc fail");
		return;
	}
	newnode->val = x;
	newnode->next = NULL;
	//链表的尾插,分两种情况讨论,链表不为空和为空
	if (pq->ptail != NULL) {
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	else {
		pq->phead = pq->ptail = newnode;
	}
	pq->size++;
}

//出队列
void QueuePop(Queue* pq) {
	assert(pq);
	//不但要检查传过来的pq是否为空,还要检查pq中的节点是否为空
	assert(pq->phead);
	//只有一个节点时
	if (pq->phead->next == NULL) {
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	//有多个节点
	else {
		QNode* next = pq->phead;
		//free(pq->phead);
		//pq->phead = next;
		pq->phead = pq->phead->next;
		free(next);
	}
	pq->size--;
}

QDataType QueueFrond(Queue* pq) {
	assert(pq);
	assert(pq->phead != NULL);
	return pq->phead->val;
}

QDataType QueueBack(Queue* pq) {
	assert(pq);
	assert(pq->ptail != NULL);
	return pq->ptail->val;
}

bool QueueEmpty(Queue* pq) {
	assert(pq);
	return pq->size == 0;
}

int QueueSize(Queue* pq) {
	assert(pq);
	return pq->size;
}

test.c测试一下:

#include"Queue.h"

int main() {
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);


	printf("%d ", QueueFrond(&q));
	//QueuePop(&q);

	QueuePush(&q, 4);
	QueuePush(&q, 5);
	while (!QueueEmpty(&q)) {
		printf("%d ", QueueFrond(&q));
		QueuePop(&q);
	}
	QueueDestroy(&q);
	return 0;
}

希望我的博客可以帮到你,如果有什么问题或者建议欢迎在评论区讨论,谢谢支持~

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值