1. 程式人生 > >探究C++優先佇列

探究C++優先佇列

結構

我們平時會用到一種很高效的資料結構:優先佇列,用法和用途就不在這裡講了,那麼它的內部到底是怎麼工作的呢?為了探究,我寫了一個仿函式,用來顯示它的每次比較:

struct itn{
    bool operator()(int a,int b) {
        printf("%d %d\n",a,b);
        return a>b;   //因為經過測試,仿函式的返回值跟過載是相反的,所以這裡是從小到大
    }
};
priority_queue<int,vector<int>,itn>p;

我把1~7依次入隊,輸出是

因為入隊本來就是有序的,所以不會交換任何元素。我們可以發現每一行的輸出有點像樹的一條邊:父節點  子節點,像這樣構成的一棵樹就是一棵逐行讀入的完全二叉樹

所以,優先佇列就是一棵樹,它的排序就是堆排序

或許有的書上早就說明了,但都不如實踐得出來的更令人信服。

執行

有的人說優先佇列是程式執行中自動排序,那是因為它排序太快了(堆排序時間複雜度是log級別),實際上它只有push或pop之後才排序一次,排序完了再執行程式碼下一條。

#include<cstdio>
#include<queue>
using namespace std;
bool f;
struct itn{
	bool operator()(int a,int b) {
		putchar('>');
		if(f)return a<b; //從大到小 
		else return a>b; //從小到大
    }
};
priority_queue<int,vector<int>,itn>p;
int main()
{
	for(int i=1;i<=7;i++)p.push(i); //執行排序
	putchar('-');
	f=1;
	printf("\n%d\n",p.top());
	p.pop(); //執行排序
	printf("\n%d",p.top()); 
	return 0;
}

上面程式碼輸出為

可見 f=true 後並沒有變為從大到小,pop之後由於少了一個元素,整體調整,才輸出了最大的7。

而且在輸出了一串'>'之後才輸出'-',說明排序完了才執行程式碼下一條。