当前位置:首页 » 《资源分享》 » 正文

【数据结构】银行排队取票机的原理是什么?详解队列_DanteKing的博客

17 人参与  2021年10月22日 15:23  分类 : 《资源分享》  评论

点击全文阅读


目录

1.摘要
2.银行排队取票机的原理
3.队列的概念
4.队列的代码实现
    4.1.队列结构体
    4.2.头文件
    4.3.接口文件
    4.4.测试文件

1.摘要

本文主要介绍队列的概念以及队列的代码实现







2.银行排队取票机的原理

最近临近开学,大一的小伙伴们一定在收到录取通知书的同时,也受到了一张来自学校的学子卡吧,那大家有没有亲自去线下网点激活学子卡呢?

我一踏进银行的自动门,工作人员就让我在前面的一台机器上扫码区号了。哦,我之前还真没来过银行,第一次见这个取号机。取号机吐出来一张写有号码的单子,然后等到柜台工作人员用电子提示音叫到你的号码时,就是轮到你去办理业务了。

在这里插入图片描述

那我不禁在想了,为什么银行要推出这样一台排队取票机呢?

放在以前,来到银行,都是往一个柜台后面排队,等排前面的人办理完了,自然轮到了你。但大家有没有想过,比如你和你的朋友恰好都来银行办理业务,你在1号窗口排队,你的朋友比你晚到10分钟,在2号窗口排队。这时,1号窗口排在你的前面的客户出了点问题,工作人员花了半个小时才解决了问题。这时,你转头一看,你的朋友已经办完业务转身离开了,而你还在排队!

明明你比你朋友先到的啊!

于是,银行为了保证先来后到的公平,推出了排队取票机。先来的人领取到号小的票,后来的人领取到号大的票,只要柜台一有空闲,
柜员就会按按钮让当前等候的手持号最小票的客户上前办理业务。

“请xx号客户前往xx号柜台办理业务···请xx号客户前往xx号柜台办理业务···”

这就避免了业务办理速度对排队公平的影响。







3.队列的概念

谈了这么一大堆,有人不禁要问了:我们今天不是要聊队列的吗?队列在哪里啊?

唉,别急啊,队列,排队排好,先来后到,难道不是队列了吗?

让我们先给出队列的定义:队列是只允许一端进行插入数据操作,另一端进行删除数据操作的特殊线性表。

队列具有先进先出的性质(First in First out)。

数据入队列的一端叫做队尾,数据出队列的一端叫做队头。

在这里插入图片描述

再次想象一下银行排队的问题,我们把一个个排队的客户想象成一个个数据元素。

现在,取票机组建了一个队列。先来的客户先进入队列,后来的客户后进入队列。

当柜员叫号时,叫的永远是位于队头的客户的号码,该客户便出队列。如果又来了一个新客户,那么他取号后,便在队尾入队列。

循此以往,先来后到的准则将被严格地遵守。

先进先出!先进先出!先进先出!重要的事情说三遍!





4.队列的代码实现

4.1.队列结构体

我们想一下,队列最最重要的操作是什么呢?

对了,是入队列和出队列

入队列是在队头,需要操作头部元素。出队列是在队尾,需要操作尾部元素。

我们知道,队列是特殊的线性表。那么想一下,如果用顺序表来实现的话,头插操作的时间复杂度华为O(N),太麻烦了。那改用链表呢?有人说,链表的尾插不也是O(N)的时间复杂度吗?对,那么,我们就在头指针的基础上,再加一个尾指针

既有头指针,又有尾指针,那何不把头指针和尾指针封装到同一个结构体里去呢?

这样的操作带来了另外一个好处:只需传入该结构体的地址,就能修改头/尾指针以及头尾指针对应的节点的内容,避免了使用二级指针带来的不便。

于是,便有了一下的结构体的创建:

a)队列节点的结构体

typedef struct QueueNode
{
	QueueDataType data;
	struct QueueNode* next;
}QueueNode;

b)队列头/尾指针的结构体

typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
}Queue;

4.2.头文件

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

typedef int QueueDataType;
typedef struct QueueNode
{
	QueueDataType data;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
}Queue;

void QueueInit(Queue* que);
void QueueDestroy(Queue* que);
void QueuePush(Queue* que, QueueDataType x);
void QueuePop(Queue* que);
QueueDataType QueueTop(Queue* que);
int QueueEmpty(Queue* que);
size_t QueueSize(Queue* que);

4.3.接口文件

void QueueInit(Queue* que)
{
	assert(que);
	que->head = NULL;
	que->tail = NULL;
}
void QueueDestroy(Queue* que)
{
	assert(que);
	QueueNode* cur = que->head;
	while (cur)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	que->tail = NULL;
}
void QueuePush(Queue* que, QueueDataType x)
{
	assert(que);
	if (que->head == NULL)
	{
		que->head = que->tail = (QueueNode*)malloc(sizeof(QueueNode));
		que->head->data = x;
		que->head->next = NULL;
	}
	else
	{
		que->tail->next = (QueueNode*)malloc(sizeof(QueueNode));
		que->tail = que->tail->next;
		que->tail->data = x;
		que->tail->next = NULL;
	}
}
void QueuePop(Queue* que)
{
	assert(que);
	assert(!QueueEmpty(que));
	QueueNode* next = que->head->next;
	free(que->head);
	que->head = next;
}
QueueDataType QueueTop(Queue* que)
{
	assert(que);
	assert(!QueueEmpty(que));
	return que->head->data;
}
int QueueEmpty(Queue* que)
{
	return que->head == NULL;
}
size_t QueueSize(Queue* que)
{
	assert(que);
	QueueNode* cur = que->head;
	size_t count = 0;
	while(cur)
	{
		++count;
		cur = cur->next;
	}
	return count;
}

4.4.测试文件

void Test1()
{
	Queue q;
	QueueInit(&q);

	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);

	printf("%d\n", QueueSize(&q));

	printf("%d\n", QueueTop(&q));

	QueuePop(&q);
	printf("%d\n", QueueTop(&q));

	QueuePop(&q);
	printf("%d\n", QueueTop(&q));

	QueuePop(&q);
	printf("%d\n", QueueTop(&q));

	QueuePop(&q);

	printf("%d\n", QueueSize(&q));

	QueueDestroy(&q);
}

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


点击全文阅读


本文链接:http://zhangshiyu.com/post/30097.html

队列  排队  指针  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1