堆的操作(priority_queue容器的介绍)

本文介绍了堆的概念,包括大顶堆和小顶堆,并重点讲解了C++ STL中的priority_queue,它是通过堆实现的优先队列。文章详细阐述了priority_queue的定义、元素访问及优先级设置,特别提到了如何为不同类型的数据设置优先级,并给出了结构体优先级设置的示例,同时强调了在使用top()函数前要检查队列是否为空的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆的介绍

堆是一颗完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。其中,如果父亲结点的值大于或等于孩子结点的值,那么称这样的堆为大顶堆。如果父亲结点的值小于或等于孩子结点的值,那么称这样的堆为小顶堆。
堆的常用操作代码实现:

#include<iostream>
#include<algorithm> 
using namespace std;
const int maxn=100;
int heap[maxn],n=10;
//对heap数组在[low,high]范围进行向下调整 
//其中low为欲调整结点的数组下标,high一般为堆最后一个元素的数组下标 
void downAdjust(int low,int high){
	int i=low,j=i*2;		//i为欲调节结点,j为其左孩子 
	while(j<=high){		//存在孩子结点
	//如果右孩子存在,且右孩子的值大于左孩子 
		if(j+1<=high&&heap[j+1]>heap[j])
			j=j+1;		//让j存储右孩子下标 
		//如果孩子中最大的权值比欲调整结点i大 
		if(heap[j]>heap[i]){
			swap(heap[j],heap[i]);		//交换最大权值的孩子与欲调整结点i 
			i=j;	//保持i为欲调整结点,j为i的左孩子 
			j=i*2;
		}
		else{
			break;		//孩子的权值均比欲调整结点i小,调整结束 
		}
	}
}
//对heap数组在[low,high]范围进行向上调整 
//其中low为一般设置为1,high表示欲调整结点的数组下标 
void upAdjust(int low,int high){
	int i=high,j=i/2;		//i为欲调节结点,j为其父亲 
	while(j>=high){		//父亲在[low,high]范围内 
		//如果孩子中最大的权值比欲调整结点i小 
		if(heap[j]<heap[i]){
			swap(heap[j],heap[i]);		//交换父亲和欲调整结点i 
			i=j;	//保持i为欲调整结点,j为i的左孩子 
			j=i/2;
		}
		else{
			break;		//父亲的权值均比欲调整结点i大,调整结束 
		}
	}
}
//建堆
void createHeap(){
	for(int i=n/2;i>=1;i--)
		downAdjust(i,n);
} 
//删除堆顶元素
void deleteTop(){
	heap[1]=heap[n--];	//用最后一个元素覆盖堆顶元素,并让元素个数减1 
	downAdjust(1,n);
} 
//添加元素x
void insert(int x){
	heap[++n]=x;		//让元素个数加1,然后将数组末位赋值为x 
	upAdjust(1,n);		//向上调整新加入的结点n 
} 
//堆排序
void heapSort(){
	createHeap();	//建立堆 
	for(int i=n;i>1;i--){		//倒着枚举,直到堆中只有一个元素 
		swap(heap[i],heap[1]);		//交换heap[i]与堆顶 
		downAdjust(1,i-1);		//调整堆顶 
	}
} 
int main()
{
	
}

priority_queue的介绍

但在实际使用过程中往往通过c++STL库中的priority_queue来使用堆。
priority_queue又称优先队列,其底层是用堆来进行实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
1.priority_queue的定义
要使用优先队列,应先添加头文件#include<queue>
其定义的写法和其他STL容器相同,typename可以是任意基本数据类型或容器:

priority_queue<typename> name;

2.priority_queue容器内元素的访问
和队列不一样的是,优先队列没有front()函数与back()函数,而只能通过top()函数来访问队首元素(也可以称为堆顶元素),也就是优先级最高的元素。

priority_queue<int> q;
q.top();

3.priority_queue内元素优先级的设置
如何定义优先队列内元素的优先级是运用好优先队列的关键
(1)基本数据类型的优先级设置
优先队列对他们的优先级设置一般是数字大的优先级越高,因此队首元素就是优先队列内元素最大的那个(如果char型,则是字典序最大的)。对基本数据类型来说,下面两种优先队列的定义是等价的:

priority_queue<int> q;
priority_queue<int,vector<int>,less<int>>q;

第二个参数(vector<int>)填写的是来自承接底层数据结构堆(heap)的容器,该参数类型必须与第一个参数类型相同,第三个参数less<int>则是对第一个参数的比较类,less<int>表示数字大的优先级越大,而greater<int>表示数字小的优先级越大。
(2)结构体的优先级设置

struct fruit{
	string name;
	int price;
	friend bool operator<(fruit f1,fruit f2){
		return f1.price<f2.price;
	}
}

上面的结构体中对小于号进行重载,重载大于号会编译错误,因为从数学角度来说只需重载小于号,即f1>f2等价于判断f2<f1,而f1==f2则等于判断!(f1 < f2)&&!(f2 < f1)。

注意:
使用top()函数前,建议用empty()判断优先队列是否为空,否则可能因为队空而出现错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值