C++ 的优先队列priority_queue

    c++ 中有小堆顶和大堆顶两种数据结构,他们分别的含义是父节点比两个子节点都大或者都小。如此一来堆栈的最顶部就是最大的或者是最小的。大小堆顶一般是hi用连续的容器实现的,比如说数组,vector,queue等。不可以用不连续的容器来实现。主要的 原因是联系连续的数组可以任意地址访问,大小堆顶如果知道了父节点的索引,那么久可以很快的计算出两个子节点的索引。所以需要用连续的容器来作为实现的底层。大小堆的每次插入和删除的时间复杂度都是logn的。(PS给你一个无序的数组,建堆的时间复杂度是O(n)的)。


 

  C++ 里面实现的大小堆顶是priority_queue这个容器,头文件是queue。常见的函数有:

  • top 访问队头元素
  • empty 队列是否为空
  • size 返回队列内元素个数
  • push 插入元素到队尾 (并排序)
  • emplace 原地构造一个元素并插入队列  
  • pop 弹出队头元素
  • swap 交换内容

   定义: priority_queue<Type, Container, Functional> name

   其中的functional 是比较方式,默认是大堆顶,也就是greater<int> 

  Type 是数据的类型,Container是容器的类型,默认是vector

  如果是基本的数据类型,那么可以直接传入需要的数据类型

#include <iostream>
#include <vector>
#include <algorithm>
#include <list>
#include <set>
#include <queue>
using namespace std;

int main()
{

	priority_queue<int> priorityQueue;
    //	priority_queue<int,vector<int>,greater<int> > priorityQueue;

	priorityQueue.push(10);
	
	priorityQueue.push(12);

	priorityQueue.push(11);

	priorityQueue.push(5);

	while (!priorityQueue.empty())
	{
		cout << priorityQueue.top() << endl;
		priorityQueue.pop();
	}

}

    如果是自己的定义读数据类型,就需要完整的写入整个定义了

#include <iostream>
#include <vector>
#include <algorithm>
#include <list>
#include <set>
#include <queue>
using namespace std;

int main()
{

     priority_queue<My_Data,vector<My_Data>,conpare> priorityQueue;


	while (!priorityQueue.empty())
	{
		cout << priorityQueue.top() << endl;
		priorityQueue.pop();
	}

}

 


    期中,说明一下emplace是C++ 11 里面新引入的三个成员函数之一,他们分别是emplace_front、emplace和emplace_back,这些操作构造而不是拷贝元素。这些操作分别对应push_front、insert和push_back,允许我们将元素放置在容器头部、一个指定位置之前或容器尾部。

    当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理的内存空间中直接构造元素。

    emplace函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。emplace函数在容器中直接构造元素。传递给emplace函数的参数必须与元素类型的构造函数相匹配。

      其它容器中,std::forward_list中的emplace_after、emplace_front函数,std::map/std::multimap中的emplace、emplace_hint函数,std::set/std::multiset中的emplace、emplace_hint,std::stack中的emplace函数,等emplace相似函数操作也均是构造而不是拷贝元素。

emplace相关函数可以减少内存拷贝和移动。当插入rvalue,它节约了一次move构造,当插入lvalue,它节约了一次copy构造。

  使用代码如下:详情见参考文献[1]

namespace {
class Dat {
	int i;
	std::string ss;
	char c;
 
public:
	Dat(int ii, std::string s, char cc) :i(ii), ss(s), c(cc) { }
 
	~Dat() { }
};
}
 
int test_emplace_4()
{
	std::vector<Dat> vec;
	vec.reserve(3);
 
	vec.push_back(Dat(89, "New", 'G')); // efficiency lesser
	//vec.push_back(678, "Newer", 'O'); // error,push_back can’t accept three arguments
	vec.emplace_back(890, "Newest", 'D'); // work fine, efficiency is also more
 
	return 0;
}
 
} // namespace emplace_

 


参考文献:[1]  https://blog.csdn.net/fengbingchun/article/details/78670376

参考文献:[2] https://blog.csdn.net/weixin_36888577/article/details/79937886

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页