手把手教数据结构与算法:优先级队列(银行排队问题)

news2024/11/18 21:28:58

队列

基本概念

队列的定义

队列(Queue):队列是一种常见的数据结构,遵循先进先出(First-In-First-Out, FIFO)的原则。在队列中,元素按照进入队列的顺序排列。队列是一个线性的数据结构,并且这个数据结构只允许在一端进行插入,另一端进行删除,禁止直接访问除这两端以外的一切数据。


队首(Front):最先进入队列的元素,可以被访问或移除
队尾(Rear):最后进入队列的元素,不允许进行访问和删除的另一端。
空队列:不含任何元素的队列。

队列的特点

队列是一种先进先出(First in First out,FIFO)的数据类型。每次元素的入队都只能添加到队列尾部,出队时从队列头部开始出。

队列的常见基本操作

  1. 入队(Enqueue):将新元素添加到队列的末尾(队尾)。

  2. 出队(Dequeue):移除队列中的第一个元素(队首)。

  3. 获取队首元素(Front):获取队列中的第一个元素,但不将其从队列中移除。

  4. 获取队列大小(Size):获取队列中当前元素的数量。

  5. 检查队列是否为空(IsEmpty):检查队列中是否有元素。

优先级队列

上文已经提到了队列先进先出的特点,而优先级队列不满足先进先出的条件,更像是数据类型中的“堆”。

入队(Enqueue):优先级队列入队时会根据优先级来考虑哪个元素先入队,优先级可以通过元素的大小等进行定义。比如定义元素越大优先级越高,则元素大的先入队。

出队(Dequeue):优先级队列每次出队的元素是队列中优先级最高的那个元素,而不是队首的元素。比如定义元素越大优先级越高,那么每次出队,都是将当前队列中最大的那个元素出队。

队列通常用于模拟排队的场景,如任务调度、消息传递等。在计算机科学中,队列也是广泛应用的一种数据结构,在算法设计和实现中发挥着重要作用。所以下面让我们动手实现一个优先级队列,用来模拟银行排队问题

队列的应用

银行排队问题

题目描述

假设银行有 K 个柜台,所有顾客按到达时间排队,当有柜台空闲,队伍最前面的顾客前往空闲柜台处理事务,求顾客的平均排队时间(排队时间=到空闲柜台开始处理事务时间-到达时间)。

提示

用优先级队列实现,并且以到达时间和服务时间作为数组输入

输入

第一行输入柜台个数≥1——int 型;
第二行输入顾客个数≥1——int 型;
第三行输入每位顾客的到达时间≥0——int 型数组,默认升序。
第四行输入每位顾客的服务时间≥0——int 型数组;

输出

第一行输出顾客的平均排队时间——int 型,向下取整。

样例输入

1

10

0 1 2 3 4 5 6 7 8 9

10 10 10 10 10 10 10 10 10 10

样例输出

40

解题思路

该问题要求模拟银行顾客排队的过程,通过输入柜台数、顾客数、每位顾客的到达时间和服务时间,模拟了顾客在银行排队办理业务的过程,计算顾客的平均排队时间。解题思路如下:

  1. 创建优先级队列:使用优先级队列来模拟顾客的排队情况。队列中的元素按到达时间排序,即到达时间越早的顾客排在队列前面。这样,在柜台空闲时,就可以直接从队列头部取出顾客进行服务。

  2. 初始化:读取输入的柜台个数、顾客个数、到达时间数组和服务时间数组。将顾客的到达时间和对应的服务时间插入到优先级队列中。

  3. 模拟排队过程:开始模拟银行排队的过程,直到所有顾客都被服务完毕为止。在每个时间点,检查是否有柜台空闲,如果有,则从队列中取出最早到达的顾客进行服务,计算其排队时间并累加到总的排队时间中。

  4. 计算平均排队时间:将总的排队时间除以顾客总数,即可得到平均排队时间,向下取整并输出结果

代码实现

结点类(node)

首先是队列的结点设计,可以设计出两个结构体,一个结构体 Node 表示结点,其中包含有 data 域和 next 指针,如下图:


其中 data 表示数据,其可以是简单的类型,也可以是复杂的结构体,故采用泛型编程template<typename eT>。next 指针表示,下一个的指针,其指向下一个结点,通过 next 指针将各个结点链接。结点类还有构造函数,在创建结点时可以进行初始化,

template<typename eT>
class node {
public:
	eT data;
	node* next;
	node(const eT& data_, node<eT>* next_ = NULL)
	{
		data = data_;
		next = next_;
	}
	node() : next(NULL) {}
	~node() {}
};
自定义队列(linkQueue)

自定义队列linkQueue采用泛型编程,其中 eT 是模板参数,代表队列中元素的类型。

front 和 tail 分别是指向队列前端和尾端的指针,用于操作队列中的元素。

构造函数和析构函数

构造函数用于初始化队列,将 front 和 tail 初始化为 NULL,表示队列为空。

析构函数用于释放队列中所有节点的内存。它通过循环遍历队列中的所有节点,逐个删除节点,并更新 front 指针,直到队列为空。

成员函数 isEmpty

isEmpty函数用于检查队列是否为空,如果front指针为空,则队列为空,返回true,否则返回false

成员函数 enQueue

enQueue 函数用于向队列尾部添加一个新元素。如果队列为空(即 tail 为空),则创建一个新节点,将 front 和 tail 都指向该节点。如果队列非空,则在 tail 指向的节点后面添加一个新节点,并更新 tail 指针。

成员函数 deQueue

deQueue 函数用于从队列头部移除一个元素,并返回其值。

首先保存队列头部节点的指针 tmp,并保存头部节点的值到 value 中。

然后更新 front 指针,指向原头部节点的下一个节点。如果队列只有一个节点(即移除后为空),则将 tail 也置为空。

最后释放原头部节点的内存,并返回其值。

template<typename eT>
class linkQueue{
public:
	node<eT>* front, * tail;
public:
	linkQueue() { front = tail = NULL; }
	~linkQueue() {
		node<eT>* tmp;
		while (front != NULL) {
			tmp = front;
			front = front->next;
			delete tmp;
		}
	}
	bool isEmpty() { return front == NULL; }
	void enQueue(const eT& x) {
		if (tail == NULL)
			front = tail = new node<eT>(x);
		else {
			tail->next = new node<eT>(x);
			tail = tail->next;
		}
	}
	eT deQueue() {
		node<eT>* tmp = front;
		eT value = front->data;
		front = front->next;
		if (front == NULL) tail = NULL;
		delete tmp;
		return value;
	}
};
优先级队列(priorityQueue)

与自定义队列(linkQueue)相同,采用泛型编程,其中 eT 是模板参数,代表队列中元素的类型。front 和 tail 分别是指向队列前端和尾端的指针,用于操作队列中的元素。

同样地,优先级队列(priorityQueue)与自定义队列(linkQueue)的初始化,判断非空,出队操作基本相同,主要不同点在于入队操作。

成员函数 enQueue

enQueue 函数用于向队列尾部添加一个新元素。如果队列为空(即 tail 为空),则创建一个新节点,将 front 和 tail 都指向该节点。如果队列非空,则寻找较大元素的前继结点进行插入操作,以保持队列的有序性。

template <typename eT>
class priorityQueue {
public:
	node<eT>* front, * tail;
	priorityQueue() { front = tail = NULL; }
	~priorityQueue() {
		node<eT>* tmp;
		while (front != NULL) {
			tmp = front;
			front = front->next;
			delete tmp;
		}
	}
	bool isEmpty() { return front == NULL; }
	eT deQueue() {
		node<eT>* tmp = front;
		eT value = front->data;
		front = front->next;
		if (front == NULL) tail = NULL;
		delete tmp;
		return value;
	}
	void enQueue(const eT& x) {
		if (tail == NULL)
			front = tail = new node<eT>(x);
		else {
			node<eT>* p;
			if (x < front->data)
			{
				p = new node<eT>(x, front);  front = p;
			}
			else {
				p = front;
				while (p->next != NULL && p->next->data < x) p = p->next;
				if (p->next == NULL)
				{
					tail->next = new node<eT>(x);
					tail = tail->next;
				}
				else  p->next = new node<eT>(x, p->next);
			}
		}
	}
};

模拟银行排队系统(simulator)

成员变量

1.noOfServer:表示银行柜台的数量。

2.customNum:表示顾客的数量。

3.arrivalTimeList:存储每位顾客到达银行的时间。

4.serviceTimeList:存储每位顾客所需的服务时间。

内部结构体 eventT

1.用于描述事件,包括事件发生时间 time 和事件类型 type(0 表示到达,1 表示离开)。

2.重载了小于操作符,以便将事件按照发生时间进行排序。

class simulator {
		int noOfServer;
		int customNum;
		int* arrivalTimeList;
		int* serviceTimeList;
		struct eventT
		{
			int time; //事件发生时间
			int type; //事件类型。0 为到达,1 为离开
			bool operator<(const eventT& e) const { return time < e.time; }
		};
};
构造函数和析构函数

构造函数从标准输入中读取柜台数、顾客数以及每位顾客的到达时间和服务时间,然后分配内存给 arrivalTimeList 和 serviceTimeList,分别用这两个数组储存每位顾客的到达时间和服务时间

析构函数释放动态分配的内存,防止内存泄漏

public:
		simulator() {
			//std::cout << "请输入柜台数:";
			std::cin >> noOfServer;
			//std::cout << "请输入模拟的顾客数:";
			std::cin >> customNum;
			arrivalTimeList = new int[customNum];
			serviceTimeList = new int[customNum];
			for (int i = 0; i < customNum; i++) {
				std::cin >> arrivalTimeList[i];
			}
			for (int i = 0; i < customNum; i++) {
				std::cin >> serviceTimeList[i];
			}
		}
		~simulator() {
			delete arrivalTimeList;
			delete serviceTimeList;
		}
成员函数avgWaitTime

该函数用来模拟顾客排队,到达和离开的过程,并且计算出平均等待时间。在该函数中我们需要用自定义队列(linkQueue)来存储等待的顾客事件和顾客的服务时间,并且用优先级队列(priorityQueue)存储顾客到达和离开的事件。

1.定义变量并进行初始化

变量表示的内容已注释

int serverBusy = 0; // 记录当前服务中的柜台数量
int serviceTime = 0; // 记录当前服务所需时间
int currentTime = 0; // 记录当前时间
int totalWaitTime = 0; // 记录总的等待时间
linkQueue<eventT> waitQueue; // 等待队列,存储等待的顾客事件
priorityQueue<eventT> customerQueue; // 顾客队列,存储到达和离开的顾客事件
linkQueue<int> serviceTimeQueue; // 服务时间队列,存储顾客的服务时间
eventT currentEvent; // 当前事件
2.生成初始事件队列
for (int i = 0; i < customNum; ++i) {
    currentEvent.type = 0;
    currentTime = arrivalTimeList[i]; // 每个顾客的到达时刻
    currentEvent.time = currentTime;
    customerQueue.enQueue(currentEvent); // 将顾客到达事件加入到顾客队列中
    serviceTimeQueue.enQueue(serviceTimeList[i]); // 将顾客的服务时间加入到服务时间队列中
}
3.模拟顾客到达和离开的过程

(1)用while循环不断取出顾客队列,直到顾客队列为空,即所有顾客都已经离开银行。从顾客队列中取出事件,并将其赋值给 currentEvent,将当前时间更新为当前事件的发生时间,即顾客到达或离开的时间。

(2)根据事件类型进行处理

a.顾客到达

如果有空闲的柜台,则顾客直接前往柜台处理业务,将当前事件的结束时间继续存入顾客队列,即顾客离开;如果所有柜台都忙碌,则顾客加入等待队列。

b.顾客离开

如果等待队列不为空,则从等待队列中取出顾客,并计算顾客等待的时间;如果等待队列为空,则只需更新柜台的繁忙状态。

while (!customerQueue.isEmpty()) {
    currentEvent = customerQueue.deQueue(); // 取出顾客队列中的事件
    currentTime = currentEvent.time; // 更新当前时间
    switch (currentEvent.type) {
        case 0: // 顾客到达事件
            if (serverBusy < noOfServer) { // 如果有空闲的柜台
                serverBusy++;
                currentEvent.time = currentTime + serviceTimeQueue.deQueue(); // 计算顾客服务结束时间
                currentEvent.type = 1; // 设置事件类型为离开
                customerQueue.enQueue(currentEvent); // 将离开事件加入到顾客队列中
            } else { // 如果所有柜台都忙碌
                waitQueue.enQueue(currentEvent); // 将顾客加入等待队列
            }
            break;
        case 1: // 顾客离开事件
            if (!waitQueue.isEmpty()) { // 如果等待队列不为空
                serverBusy--;
                currentEvent = waitQueue.deQueue(); // 取出等待队列中的顾客事件
                totalWaitTime += currentTime - currentEvent.time; // 计算等待时间
                currentEvent.time = currentTime + serviceTimeQueue.deQueue(); // 计算顾客服务结束时间
                currentEvent.type = 1; // 设置事件类型为离开
                customerQueue.enQueue(currentEvent); // 将离开事件加入到顾客队列中
            } else {
                serverBusy--;
            }
            break;
        default:
            break;
    }
}
4.返回平均等待时间
return totalWaitTime / customNum; // 返回平均等待时间

完整代码

#include<iostream>
#include<stdlib.h>
#include<queue>
using namespace std;
template<typename eT>
class node {
public:
	eT data;
	node* next;
	node(const eT& data_, node<eT>* next_ = NULL)
	{
		data = data_;
		next = next_;
	}
	node() : next(NULL) {}
	~node() {}
};
template<typename eT>
class linkQueue{
public:
	node<eT>* front, * tail;
public:
	linkQueue() { front = tail = NULL; }
	~linkQueue() {
		node<eT>* tmp;
		while (front != NULL) {
			tmp = front;
			front = front->next;
			delete tmp;
		}
	}
	bool isEmpty() { return front == NULL; }
	void enQueue(const eT& x) {
		if (tail == NULL)
			front = tail = new node<eT>(x);
		else {
			tail->next = new node<eT>(x);
			tail = tail->next;
		}
	}
	eT deQueue() {
		node<eT>* tmp = front;
		eT value = front->data;
		front = front->next;
		if (front == NULL) tail = NULL;
		delete tmp;
		return value;
	}
};
template <typename eT>
class priorityQueue {
public:
	node<eT>* front, * tail;
	priorityQueue() { front = tail = NULL; }
	~priorityQueue() {
		node<eT>* tmp;
		while (front != NULL) {
			tmp = front;
			front = front->next;
			delete tmp;
		}
	}
	bool isEmpty() { return front == NULL; }
	eT deQueue() {
		node<eT>* tmp = front;
		eT value = front->data;
		front = front->next;
		if (front == NULL) tail = NULL;
		delete tmp;
		return value;
	}
	void enQueue(const eT& x) {
		if (tail == NULL)
			front = tail = new node<eT>(x);
		else {
			node<eT>* p;
			if (x < front->data)
			{
				p = new node<eT>(x, front);  front = p;
			}
			else {
				p = front;
				while (p->next != NULL && p->next->data < x) p = p->next;
				if (p->next == NULL)
				{
					tail->next = new node<eT>(x);
					tail = tail->next;
				}
				else  p->next = new node<eT>(x, p->next);
			}
		}
	}
};
class simulator {
		int noOfServer;
		int customNum;
		int* arrivalTimeList;
		int* serviceTimeList;
		struct eventT
		{
			int time; //事件发生时间
			int type; //事件类型。0 为到达,1 为离开
			bool operator<(const eventT& e) const { return time < e.time; }
		};
	public:
		simulator() {
			//std::cout << "请输入柜台数:";
			std::cin >> noOfServer;
			//std::cout << "请输入模拟的顾客数:";
			std::cin >> customNum;
			arrivalTimeList = new int[customNum];
			serviceTimeList = new int[customNum];
			for (int i = 0; i < customNum; i++) {
				std::cin >> arrivalTimeList[i];
			}
			for (int i = 0; i < customNum; i++) {
				std::cin >> serviceTimeList[i];
			}
		}
		~simulator() {
			delete arrivalTimeList;
			delete serviceTimeList;
		}
		int avgWaitTime() {
			int serverBusy = 0;
			int serviceTime = 0;
			int currentTime = 0;
			int totalWaitTime = 0;
			linkQueue<eventT> waitQueue;
			priorityQueue<eventT> customerQueue;
			linkQueue<int> serviceTimeQueue;
			eventT currentEvent;
			//生成初始的事件队列
			int i;
			for (i = 0; i < customNum; ++i)
			{
				currentEvent.type = 0;
				currentTime = arrivalTimeList[i];//每个顾客的到达时刻
				currentEvent.time = currentTime;
				customerQueue.enQueue(currentEvent);
				serviceTimeQueue.enQueue(serviceTimeList[i]);//每个顾客的服务时间
			}
			while (!customerQueue.isEmpty())
			{
				currentEvent = customerQueue.deQueue();
				currentTime = currentEvent.time;
				switch (currentEvent.type)
				{
				case 0:					
					if (serverBusy < noOfServer)
					{
						serverBusy++;
						currentEvent.time = currentTime + serviceTimeQueue.deQueue();
						currentEvent.type = 1;
						customerQueue.enQueue(currentEvent);
					}
					else {
						waitQueue.enQueue(currentEvent);
					}
					break;
				case 1:
				{
					if (waitQueue.isEmpty() == 0)
					{
						serverBusy--;
						currentEvent = waitQueue.deQueue();
						totalWaitTime = totalWaitTime + currentTime - currentEvent.time;
						currentEvent.time = currentTime + serviceTimeQueue.deQueue();
						currentEvent.type = 1;
						customerQueue.enQueue(currentEvent);
					}
					else serverBusy--;
					break;
				}
				default:break;
				}
			}
			return totalWaitTime / customNum;
		}
	};
	int main()
	{
		simulator sim;
		cout << sim.avgWaitTime() <<endl;
		return 0;
	}

附录

分类专栏

链接:

​​​​​手把手教数据结构与算法

本专栏上一节

链接:

手把手教数据结构与算法:栈的应用(平衡符号和简单计算器)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1637102.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【PPT设计】颜色对比、渐变填充、简化框线、放大镜效果、渐变形状配图、线条的使用

目录 图表颜色对比、渐变填充、简化框线放大镜效果渐变形状配图 线条的使用区分标题与说明信息区分标题与正文,区分不同含义的内容**聚焦****引导****注解****装饰** 图表 颜色对比、渐变填充、简化框线 小米汽车正式亮相&#xff01;你们都在讨论价格&#xff0c;我全程只关…

【C语言】指针篇- 深度解析Sizeof和Strlen:热门面试题探究(5/5)

&#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;C笔记专栏&#xff1a; C笔记 &#x1f308;喜欢的诗句:无人扶我青云志 我自踏雪至山巅 文章目录 一、简单介绍Sizeof和Strlen1.1 Sizeof1.2 Strlen函数1.3 Sie…

几个容器网络问题实战解析

容器云平台和容器网络紧密结合&#xff0c;共同构建了容器化应用程序的网络基础设施&#xff0c;实现了容器之间的通信、隔离和安全性。文中容器云平台采用的容器网络组件是calico&#xff0c;这个是业界普遍采用的一种方案&#xff0c;性能及安全性在同类产品中都是比较好的。…

【UnityRPG游戏制作】Unity_RPG项目_玩家逻辑相关

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;就业…

Android Studio 调试:快速入门指南

作为一名Android应用开发人员&#xff0c;调试是你不可或缺的技能之一。通过调试&#xff0c;你可以定位和解决各种问题&#xff0c;包括崩溃、性能问题、UI错误等。在本文中&#xff0c;我们将分享一些实用的Android调试技巧&#xff0c;帮助你提高应用开发效率。 Android St…

Delta lake with Java--将数据保存到Minio

今天看了之前发的文章&#xff0c;居然有1条评论&#xff0c;看到我写的东西还是有点用。 今天要解决的问题是如何将 Delta产生的数据保存到Minio里面。 1、安装Minio&#xff0c;去官网下载最新版本的Minio&#xff0c;进入下载目录&#xff0c;运行如下命令&#xff0c;曾经…

动态规划——记忆化递归

1.情景导入 你应该知道斐波那契数列吧&#xff01;就是前两项之和等于这一项。如果你学过递归&#xff0c;你肯定会写这道题&#xff1a;输入一个N代表你要求的项数&#xff0c;然后输出斐波那契的第N项。这道题看似简单&#xff0c;实则也挺简单实则特别困难&#xff08;对于…

C++学习第十五课:类型转换运算符的深度解析

C学习第十五课&#xff1a;类型转换运算符的深度解析 类型转换是编程中常见的需求&#xff0c;C提供了多种类型转换方式&#xff0c;包括静态类型转换和动态类型转换。此外&#xff0c;还可以通过类型转换运算符自定义转换行为。本课将深入探讨C中的类型转换机制&#xff0c;包…

Visual Source Safe 安装与使用教程

1.VSS 的工作原理: Microsott的 vss讲所有的项目源文件(包括各种文件类型)以特有的方式存入数据库。用户成员不能对该数据库中的文件进行直接的修改,而是由版本管理器将该项目的远程序或是子项目的程序拷贝到各个用户成员自己的工作目录下进行调试和修改,然后将修改后的项目…

[ log日志画图]分割模型训练结束生成相关日志运用代码画图

文章目录 [ log日志画图]分割模型训练结束生成相关日志运用代码画图我的log文件&#xff1a;画图&#xff1a;1.loss1.1 loss是干嘛的1.2 代码1.3 生成图 2.DICE.IOU2.1 DICE,IOU是干嘛的(常规介绍)2.2 代码2.3 生成图小白tip [ log日志画图]分割模型训练结束生成相关日志运用代…

《Redis使用手册之Lua脚本》

《Redis使用手册之Lua脚本》 EVAL&#xff1a;执行脚本 127.0.0.1:6379> eval “return ‘hello world’” 0 “hello world” 127.0.0.1:6379> eval “return redis.call(‘set’,KEYS[1],ARGV[1])” 1 “message” “hello world” OK 127.0.0.1:6379> get message…

基于FPGA的数字信号处理(5)--Signed的本质和作用

前言 Verilog中的signed是一个很多人用不好&#xff0c;或者说不太愿意用的一个语法。因为不熟悉它的机制&#xff0c;所以经常会导致运算结果莫名奇妙地出错。其实了解了signed以后&#xff0c;很多时候用起来还是挺方便的。 signed的使用方法主要有两种&#xff0c;其中一种…

【Windows,亲测有效】手动激活Sublime Text

前言 Sublime Text 是一款非常好用的文本编辑器&#xff0c;但是免费版时不时会跳弹窗 本方法无毒无害&#xff0c;简单易上手 2023/12/22 更新&#xff1a;实测从 4143 支持到 4169 开始 先确保你用的是官方版本的 Sublime Text&#xff0c;还没下的可以去官方下载&#…

TiDB系列之:部署TiDB集群常见报错解决方法

TiDB系列之&#xff1a;部署TiDB集群常见报错解决方法 一、部署TiDB集群二、unsupported filesystem ext3三、soft limit of nofile四、THP is enabled五、numactl not usable六、net.ipv4.tcp_syncookies 1七、service irqbalance not found,八、登陆TiDB数据库 一、部署TiDB…

【ARM 裸机】NXP 官方 SDK 使用

在前几节中&#xff0c;学习了如何编写汇编的 led 驱动、C 语言的 led 驱动、模仿 STM32 进行开发&#xff0c;我们都是自己写外设寄存器的结构体&#xff0c;外设非常的多&#xff0c;写起来费时费力&#xff0c;NXP 针对 I.MX6ULL 编写了一个 SDK 包&#xff0c;这个 SDK 包就…

C++ | Leetcode C++题解之第59题螺旋矩阵II

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<int>> generateMatrix(int n) {int num 1;vector<vector<int>> matrix(n, vector<int>(n));int left 0, right n - 1, top 0, bottom n - 1;while (left < r…

【C++】一篇文章带你深入了解stack、queue 和 priority_queue

目录 一、stack的介绍和使用1.1 stack的介绍1.2 stack的使用1.2.1.1 [stack对象的构造](https://legacy.cplusplus.com/reference/stack/stack/stack/)1.2.1.2 stack对象的容量操作1.2.1.2.1 [empty()函数](https://legacy.cplusplus.com/reference/stack/stack/empty/)1.2.1.2…

密度峰值聚类(DPC)算法(Python3实现)

一、密度峰值算法简介 1、密度峰值聚类算法 密度峰值聚类&#xff08;Density peaks clustering, DPC&#xff09;算法是由Rodriguez和Laio于2014年提出的一种聚类分析算法。其原始文献名是在在 Science上发表的&#xff0c;论文名称为“Clustering by Fast Search and Find …

requests库进行接口请求

请求的常规写法 requests.post() 、requests.get() 从中可以看出&#xff1a; 必填参数&#xff1a; url可缺省参数&#xff1a; data&#xff0c;json等、关键字参数 **kwargs 如下进行了一个post请求的登录&#xff0c;且请求体在body中 知识点1 当为post请求时&#xff1…

区块链技术:DAPP开发

随着科技的飞速发展&#xff0c;区块链技术逐渐渗透到各个领域&#xff0c;其中DAPP&#xff08;去中心化应用&#xff09;的发展尤为引人注目。作为一种新型的应用程序&#xff0c;DAPP正在重塑未来商业生态&#xff0c;其潜力无可估量。 一、DAPP的定义和特点 DAPP是指基于…