探究C++優先佇列
阿新 • • 發佈:2018-12-26
結構
我們平時會用到一種很高效的資料結構:優先佇列,用法和用途就不在這裡講了,那麼它的內部到底是怎麼工作的呢?為了探究,我寫了一個仿函式,用來顯示它的每次比較:
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。
而且在輸出了一串'>'之後才輸出'-',說明排序完了才執行程式碼下一條。