1. 程式人生 > >[C/C++]_[初級]_[std::priority_queue的介紹]

[C/C++]_[初級]_[std::priority_queue的介紹]

場景

  1. 有時候我們需要一個容器, 在插入時能按照指定的順序排列, 從而在元素全部插入後, 或者刪除某個元素時不需要重新對容器進行sort.

  2. std::vectorstd::queue 不具備這種特性. std::map的key具備這種特性, 但是缺點就是不能進行復雜的比較. std::map的使用細節

說明

  1. std::priority_queue 可以在進行插入資料時就進行比較並排序. 可以指定複雜的排序. 缺點就是隻支援一次性列舉, 如果需要列舉std::priority_queue, 那麼需要類似於queue的特性那樣pop

    出來.

  2. std::priority_queue 提供常量的時間複雜度查詢最大值. 插入和提取的時間複雜度是 對數時間(logarithmic time).

  3. Compare比較器如果使用std::greater<T>時, 最小的元素出現在top位置. 比較器使用strict weak ordering..

Establishes strict weak ordering relation with the following properties
For all a, comp(a,a)==false
If comp(a,b)==true then comp(b,a)==false
if comp(a,b)==true and comp(b,c)==true then comp(a,c)==true

例子

  1. 以下對整數比較, 日期比較的 std::priority_queue.

圖示


template<typename T>
class A
{
public:
	std::basic_string<T> date;

};

// https://en.cppreference.com/w/cpp/named_req/Compare
// https://en.cppreference.com/w/cpp/container/priority_queue
void TestPriorityQueue()
{
	std::priority_queue<int> q;
	srand(time(NULL));
	for(int i = 0; i< 10; ++i)
		q.push(rand());

	auto q1 = q; // 如果需要繼續使用 std::priority_queue 容器資料, 需要複製.
	print_queue(q); // 列印或者說列舉 queue 裡的元素, 需要 pop 出元素. 也就是隻能列舉一次.

	// 自定義比較函式
	typedef A<wchar_t> A1;
	auto Func = [](const A1& first, const A1& second)->bool{
		return first.date < second.date;
	};
	std::priority_queue<A1,std::vector<A1>,decltype(Func)> a_queue;
	long long temp = 20181001;
	for(int i = 0; i< 10;++i){
		A1 a;
		a.date = std::to_wstring(temp+i);
		a_queue.push(a);
	}
	
	while(!a_queue.empty()) {
		std::wcout << a_queue.top().date << L" ";
		a_queue.pop();
	}
	std::wcout << L'\n';
}

輸出

31180 28104 24260 23942 21404 19083 11173 8284 6993 567
20181010 20181009 20181008 20181007 20181006 20181005 20181004 20181003 20181002
 20181001

參考

C++ named requirements: Compare
std::priority_queue