堆->优先队列的学习笔记

一、堆

就是用数组实现的二叉树.
堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。

堆的常用方法:

构建优先队列
支持堆排序
快速找出一个集合中的最小值(或者最大值)

堆属性
堆分为两种:最大堆和最小堆,两者的差别在于节点的排序方式。

在最大堆中,父节点的值比每一个子节点的值都要大。
在最小堆中,父节点的值比每一个子节点的值都要小。
这就是所谓的“堆属性”,并且这个属性对堆中的每一个节点都成立。

注意:堆的根节点中存放的是最大或者最小元素,但是其他节点的排序顺序是未知的。
例如,在一个最大堆中,最大的那一个元素总是位于 index 0的位置,但是最小的元素则未必是最后一个元素。
唯一能够保证的是最小的元素是一个叶节点,但是不确定是哪一个。

下面的公式就给出了它的父节点和子节点在数组中的位置

parent(i)=i/2;
left son(i)=i*2;
right son(i)=i*2+1;

堆的几个基本操作:

            上浮 shift_up;
            下沉 shift_down
            插入 push  复杂度o(logn)
            弹出 pop  复杂度o(logn)
            取顶 top
            堆排序 heap_sort(本文没有实现)

这里对于这些实现的原理不一一赘述,想要知道的同学可以看 数据结构:堆 这里对于原理的实现讲述的非常清楚,本文主要在于代码的实现。
既然如此,那就上代码。

代码部分:如有不对,请指正qwq

class Heap{
	public:
		Heap(int p=0):op(p){size=0;};
		void push(int);
		void pop();
		int top();
		void shiftUp(int);
		void shiftDown(int);
	private:
		int a[100010];
		int size;
		int op;//op=0为大根堆,反之为小根堆 
};
void Heap::shiftUp(int i){
	if(op==1){//小根堆 
		while(i/2>=1){
			if(a[i]<a[i/2]){
				swap(a[i],a[i/2]);
				i=i/2;
			} 
		}
	}else{//大根堆 
		while(i/2>=1){
			if(a[i]>a[i/2]){
				swap(a[i],a[i/2]);
				i=i/2;
			}else break;
		}
	}
}
void Heap::shiftDown(int i){
	if(op==1){//小 
		while(i*2<=size){
			int t=i*2;
			if(t+1<=size&&a[t+1]<a[t]) t++;//取左右儿子中的最小 
			if(a[i]>a[t]){
				swap(a[i],a[t]);
				i=t;
			}else break;
		}
	}else{//大 
		while(i*2<=size){
			int t=i*2;
			if(t+1<=size&&a[t+1]>a[t]) t++;//取左右儿子中的最大 
			if(a[i]<a[t]){
				swap(a[i],a[t]);
				i=t;
			}else break;
		}
	}
}
void Heap::push(int x){
	size++;
	a[size]=x;
	shiftUp(size);
}
void Heap::pop(){
	swap(a[1],a[size]);
	size--;
	shiftDown(1);
}
int Heap::top(){
	return a[1];
}

参考:
https://www.jianshu.com/p/6b526aa481b1

https://www.cnblogs.com/JVxie/p/4859889.html

二、优先队列

优先队列和其实是队列的一种

普通队列:先进先出;后进先出

优先队列:出队顺序和入队顺序无关;和优先级相关

优先队列的接口和普通队列的接口是完全相同的,只是在出队和查看队首的实现方式会不同(优先级最高的在队首)

优先队列的实现方式多样,这里使用堆来实现优先队列,即在堆的基础上填加优先队列的接口,其实我个人认为这里堆等价于优先队列…(不大确定…如果有我遗漏或者不对的地方一定请指出来)

//用堆实现的优先队列 
/*
使用函数指针 
  greatter:从大到小
  lesss:从小到大 

void push(T);压入堆中 
void pop();弹出堆顶元素 
T top()const;返回堆顶元素的值 
int getSize()const;返回堆的大小 
bool empty()const;判断堆是否为空 
void clear();清空堆 

*/ 
#include<iostream>
#include<vector> 
using namespace std;

template<class T>
bool greatter(T a,T b){
	return a>b;
}
template<class T>
bool lesss(T a,T b){
	return a<b;
}

template <class T,bool (*cmp)(T,T)>
class PriorityQueue{
	private:
		vector<T> a;
	public:
		PriorityQueue(){};
		~PriorityQueue(){};
		void push(T);
		void pop();
		T top() const;
		void shiftUp(int);
		void shiftDown(int);
		int getSize() const;
		bool empty() const;
		void clear();
};

template <class T,bool (*cmp)(T,T)>
void PriorityQueue<T,cmp>::shiftUp(int i){
	int t=i>>1;
	while(t>=0){
		if(cmp(a[i],a[t])){
			swap(a[i],a[t]);
			i=t;
			t>>=1;
		}else break; 
	}
}

template <class T,bool (*cmp)(T,T)>
void PriorityQueue<T,cmp>::shiftDown(int i){
	int size=a.size();
	int t=i<<1;
	while(t<size){
		if(t+1<size&&cmp(a[t+1],a[t])) t++;
		if(cmp(a[t],a[i])){
			swap(a[i],a[t]);
			i=t;
			t<<=1;
		}else break;
	}
}

template <class T,bool (*cmp)(T,T)>
void PriorityQueue<T,cmp>::push(T x){
	a.push_back(x);
	int n=a.size()-1;
	shiftUp(n);
}

template <class T,bool (*cmp)(T,T)>
void PriorityQueue<T,cmp>::pop(){
	int n=a.size()-1;
	a[0]=a[n];
	a.pop_back(); 
	shiftDown(0);
}

template <class T,bool (*cmp)(T,T)>
T PriorityQueue<T,cmp>::top() const{
	return a[0];
}

template <class T,bool (*cmp)(T,T)>
int PriorityQueue<T,cmp>::getSize() const{
	return a.size();
}

template <class T,bool (*cmp)(T,T)>
bool PriorityQueue<T,cmp>::empty() const{
	if(a.size()==0) return true;
	return false;
}

template <class T,bool (*cmp)(T,T)>
void PriorityQueue<T,cmp>::clear(){
	a.clear(); 
}

int main()
{
	cout<<"测试:"<<endl;
	
	PriorityQueue<int,greatter> h1;
	PriorityQueue<int,lesss> h2;
	
	cout<<"输入测试数据的个数:"<<endl; 
	int n;cin>>n;
	
	cout<<"输入测试数据"<<endl;
	for(int i=1;i<=n;i++){
		int x;cin>>x;
		h1.push(x);
		h2.push(x);  
	}  
	
	cout<<"堆的大小为:"<<h1.getSize()<<endl; 
	cout<<"大根堆按序输出:"<<endl;
	for(int i=1;i<=n;i++){
		cout<<h1.top()<<" ";
		h1.pop();
	}
	if(h1.empty()) cout<<"元素已被完全弹出"<<endl;
	else{
		cout<<"有元素未被弹出"<<endl; 
		h1.clear();
	}
	
	cout<<"堆的大小为:"<<h2.getSize()<<endl; 
	cout<<"小根堆按序输出:"<<endl;
	for(int i=1;i<=n;i++){
		cout<<h2.top()<<" ";
		h2.pop();
	}
	if(h2.empty()) cout<<"元素已被完全弹出"<<endl;
	else{
		cout<<"有元素未被弹出"<<endl; 
		h2.clear();
	}
	
} 
智慧旅游解决方案利用云计算、物联网和移动互联网技术,通过便携终端设备,实现对旅游资源、经济、活动和旅游者信息的智能感知和发布。这种技术的应用旨在提升游客在旅游各个环节的体验,使他们能够轻松获取信息、规划行程、预订票务和安排食宿。智慧旅游平台为旅游管理部门、企业和游客提供服务,包括政策发布、行政管理、景区安全、游客流量统计分析、投诉反馈等。此外,平台还提供广告促销、库存信息、景点介绍、电子门票、社交互动等功能。 智慧旅游的建设规划得到了国家政策的支持,如《国家中长期科技发展规划纲要》和国务院的《关于加快发展旅游业的意见》,这些政策强调了旅游信息服务平台的建设和信息化服务的重要性。随着技术的成熟和政策环境的优化,智慧旅游的时机已经到来。 智慧旅游平台采用SaaS、PaaS和IaaS等云服务模式,提供简化的软件开发、测试和部署环境,实现资源的按需配置和快速部署。这些服务模式支持旅游企业、消费者和管理部门开发高性能、高可扩展的应用服务。平台还整合了旅游信息资源,提供了丰富的旅游产品创意平台和统一的旅游综合信息库。 智慧旅游融合应用面向游客和景区景点主管机构,提供无线城市门户、智能导游、智能门票及优惠券、景区综合安防、车辆及停车场管理等服务。这些应用通过物联网和云计算技术,实现了旅游服务的智能化、个性化和协同化,提高了旅游服务的自由度和信息共享的动态性。 智慧旅游的发展标志着旅游信息化建设的智能化和应用多样化趋势,多种技术和应用交叉渗透至旅游行业的各个方面,预示着全面的智慧旅游时代已经到来。智慧旅游不仅提升了游客的旅游体验,也为旅游管理和服务提供了高效的技术支持。
智慧旅游解决方案利用云计算、物联网和移动互联网技术,通过便携终端设备,实现对旅游资源、经济、活动和旅游者信息的智能感知和发布。这种技术的应用旨在提升游客在旅游各个环节的体验,使他们能够轻松获取信息、规划行程、预订票务和安排食宿。智慧旅游平台为旅游管理部门、企业和游客提供服务,包括政策发布、行政管理、景区安全、游客流量统计分析、投诉反馈等。此外,平台还提供广告促销、库存信息、景点介绍、电子门票、社交互动等功能。 智慧旅游的建设规划得到了国家政策的支持,如《国家中长期科技发展规划纲要》和国务院的《关于加快发展旅游业的意见》,这些政策强调了旅游信息服务平台的建设和信息化服务的重要性。随着技术的成熟和政策环境的优化,智慧旅游的时机已经到来。 智慧旅游平台采用SaaS、PaaS和IaaS等云服务模式,提供简化的软件开发、测试和部署环境,实现资源的按需配置和快速部署。这些服务模式支持旅游企业、消费者和管理部门开发高性能、高可扩展的应用服务。平台还整合了旅游信息资源,提供了丰富的旅游产品创意平台和统一的旅游综合信息库。 智慧旅游融合应用面向游客和景区景点主管机构,提供无线城市门户、智能导游、智能门票及优惠券、景区综合安防、车辆及停车场管理等服务。这些应用通过物联网和云计算技术,实现了旅游服务的智能化、个性化和协同化,提高了旅游服务的自由度和信息共享的动态性。 智慧旅游的发展标志着旅游信息化建设的智能化和应用多样化趋势,多种技术和应用交叉渗透至旅游行业的各个方面,预示着全面的智慧旅游时代已经到来。智慧旅游不仅提升了游客的旅游体验,也为旅游管理和服务提供了高效的技术支持。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
在C语言中,可以使用优先队列来实现一种特殊的队列,其中元素按照一定的优先级进行排序。C语言中没有直接提供优先队列的数据结构,但可以使用来实现优先队列是一种完全二叉树,其中每个节点的值都大于等于(或小于等于)其子节点的值。在C语言中,可以使用标准库中的函数来实现优先队列的功能。 在C语言中,可以使用priority_queue头文件来引入优先队列。可以定义一个priority_queue类型的变量,并指定元素的类型、容器类型以及比较函数。其中,比较函数可以使用greater<int>来表示小顶(即元素的优先级按照升序排列),或者使用less<int>来表示大顶(即元素的优先级按照降序排列)。 下面是一个示例程序,展示了如何在C语言中使用优先队列: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <queue> int main() { priority_queue<int, std::vector<int>, std::greater<int>> pq; pq.push(2); pq.push(1); pq.push(3); while (!pq.empty()) { printf("%d\n", pq.top()); pq.pop(); } return 0; } ``` 在这个示例程序中,我们使用了priority_queue头文件来引入优先队列。定义了一个pq变量,指定元素类型为int,容器类型为std::vector<int>,比较函数为std::greater<int>,表示小顶。然后,我们向队列中插入一些元素,然后循环打印队列中的元素并删除它们。最终的输结果是按照升序排列的。 所以,在C语言中,可以使用priority_queue头文件来实现优先队列。可以根据需要选择不同的比较函数来得到不同的优先级顺序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [c++ 优先队列(priority_queue)](https://blog.csdn.net/m0_62742402/article/details/122908053)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++学习笔记(七)~ 优先队列priority_queue)的简单使用](https://blog.csdn.net/weixin_44225182/article/details/108567330)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值