[C++] 算法 优先队列(priority_queue)

一、优先队列

        优先队列是一种特殊的队列,除了具有队列的性质(先进先出,队列头出,队列尾入),还具有一个及其重要的性质:实现快速得到队列中优先级最高的元素。 使得优先队列有一定的顺序特点,例如 从大到小 排列 和 从小到大 排列。

        例:当优先队列为从大到小排列时,队列元素的头部始终保持数值最大,并且可以通过队尾插入数据,队首移出数据等操作,始终保持队列首端元素数值最大

      上述过程,或者说优先队列的本质,其实就是堆的操作,包含了堆的插入移出操作,从大到小排列,本质就是一个大根堆,同理,从小到大排列本质就是一个小根堆


二、堆实现优先队列

        1. 访问队首元素(得到、弹出队首)

        ①访问队首元素:当堆为大根堆时(优先队列从大到小排列时),仅通过 a[1] 即可得出队首元素。

        ②弹出队首元素,再使其保持从大到小排列:

       将队首元素输出,再将队尾元素移至队首,从队首开始实现堆的向下操作,即可保持性质。

      

void headdown(int x) //大根堆 
{
	while(1)
	{		
		if(x>n) return ;
		int child1=x*2;
		int child2=child1+1;
		int maxn=child1;
		if(child1>n) return ;
		if(child2>n)
		{
			if(a[maxn]>a[x]) 
			{
				swap(a[maxn],a[x]);
				x=maxn;
			}
			else return ;
		}
		else
		{
			if(a[child1]<a[child2]) maxn=child2;
			if(a[maxn]>a[x]) 
			{
				swap(a[maxn],a[x]);
				x=maxn;
			}
			else return ;
		}
	}
}
 
-----------------------------------
 
 
printf("%d ",a[1]);
a[1]=a[n];n--;
headdown(1);

2。在优先队列中插入元素

        只需要在队尾中插入该元素,再通过向上操作保持优先队列的性质。

void heapup(int x) //向上操作 
{
	int parent=x/2;
	while(1)
	{
		if(a[x]>a[parent]) 
		{
			swap(a[x],a[parent]);
			x=parent;
			parent=x/2;
		}
		else return ; 
	}
}

 3.判断队列是否为空,队列中元素个数。

           都可以通过一个动态变量 n ,反应队列(堆)中的元素个数

三、STL实现优先队列

        在C++中,优先队列可以通过库函数实现,和队列(queue)一样,需要用到头文件            #include<queue> , 这里先讲述普通队列的操作。

      1.队列(queue)的基本操作

          ①  队列的定义初始化

queue<int> q;  // 仅含一个参数
std::queue<int> q; // 初始化一个空队列

          ② 判断队列是否为空

if(q.empty()==true)
{
    printf("empty");
}
else printf("No empty");

          ③ 获得元素个数

int n=q.size();

         ④返回、弹出队首元素 

int x=q.front(); // 获得队首元素
q.pop();  // 弹出队首元素 出队

          ⑤ 入队操作

q.push(x);

2.优先队列的STL操作

        ①优先队列的定义

priority_queue<int>q; // 默认大根堆从小到大排
 
// 等同于 priority_queue<int, vector<int>, less<int> > q;
 
// 小根堆
// 可以将大根堆的元素取负,这样从大到小排列,即为原来元素的从小到大排列
 
// priority_queue<int, vector<int>, greater<int> > q;

当队列中含有多个参数时,优先队列通常会先比较第一个元素,当第一个相等时比较第二个

priority_queue< pair<int,int> > q;
int x1=q.top().first;
int x2=q.top().second;

        ②取出队首元素(top)

int x=q.top();

         ③入队,出队,判空,查询元素个数

        和普通队列一样

q.push(x);
q.pop();
bool x=q.empty();
int n=q.size();

四、优先队列的说明

        由于优先队列的本质是堆,所以优先队列内部操作的时间则是堆进行操作的时间,堆进行向上操作、向下操作的时间复杂度为O(nlogn),即优先队列的时间复杂度也为 O(nlogn)

        STL中的队列和优先队列通常使得代码更简单,但是仍然需要知道队列与优先队列内部操作的过程(本质)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值