優先佇列學習之哈弗曼樹

2022-01-31 21:12:32 字數 2740 閱讀 3468

**自:

priority_queue 呼叫 stl裡面的 make_heap(), pop_heap(), push_heap() 演算法

實現,也算是堆的另外一種形式。

先寫乙個用 stl 裡面堆演算法實現的與真正的stl裡面的 priority_queue  用法相

似的 priority_queue, 以加深對 priority_queue 的理解

#include #include 

#include

using

namespace

std;

class

priority_queue

void

pop()

int top()

int size()

bool empty()

};int

main()

return0;

}

stl裡面的 priority_queue 寫法與此相似,只是增加了模板及相關的迭代器什麼的。

priority_queue 對於基本型別的使用方法相對簡單。

他的模板宣告帶有三個引數,priority_queue

type 為資料型別, container 為儲存資料的容器,functional 為元素比較方式。

container 必須是用陣列實現的容器,比如 vector, deque 但不能用 list.

stl裡面預設用的是 vector. 比較方式預設用 operator< , 所以如果你把後面倆個

引數預設的話,優先佇列就是大頂堆,隊頭元素最大。

看例子

#include #include 

using

namespace

std;

intmain()

getchar();

return0;

}

如果要用到小頂堆,則一般要把模板的三個引數都帶進去。

stl裡面定義了乙個仿函式 greater<>,對於基本型別可以用這個仿函式宣告小頂堆

例子:

#include #include 

using

namespace

std;

intmain()

getchar();

return0;

}

對於自定義型別,則必須自己過載 operator< 或者自己寫仿函式

先看看例子:

#include #include 

using

namespace

std;

struct

node

};bool

operator

<( node a, node b )

intmain()

getchar();

return0;

}

自定義型別過載 operator< 後,宣告物件時就可以只帶乙個模板引數。

但此時不能像基本型別這樣宣告

priority_queue, greater>;

原因是 greater沒有定義,如果想用這種方法定義

則可以按如下方式

例子:

#include #include 

using

namespace

std;

struct

node

};struct

cmp};

intmain()

getchar();

return0;

}

如下**自:

在乙個果園裡,多多已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。多多決定把所有的果子合成一堆。

每一次合併,多多可以把兩堆果子合併到一起,消耗的體力等於兩堆果子的重量之和。可以看出,所有的果子經過n-1次合併之後,就只剩下一堆了。多多在合併果子時總共消耗的體力等於每次合併所消耗體力之和。

因為還要花大力氣把這些果子搬回家,所以多多在合併果子時要盡可能地節省體力。假定每個果子重量都為1,並且已知果子的種類數和每種果子的數目,你的任務是設計出合併的次序方案,使多多耗費的體力最少,並輸出這個最小的體力耗費值。

例如有3種果子,數目依次為1,2,9。可以先將1、2堆合併,新堆數目為3,耗費體力為3。接著,將新堆與原先的第三堆合併,又得到新的堆,數目為12,耗費體力為12。所以多多總共耗費體力=3+12=15。可以證明15為最小的體力耗費值。

第一行是乙個整數n(1<=n<=10000),表示果子的種類數。第二行包含n個整數,用空格分隔,第i個ai(1<=ai<=20000)是第i個果子的數目。

輸出包括一行,這一行只包含乙個整數,也就是最小的體力耗費值。輸入資料保證這個值小於2^31。

3

1 2 9

15
#include #include 

#include

#include

//標頭檔案

using

namespace

std;

struct cmp//

函式從小到大排序,因為預設的優先佇列是從大到小排序

};int

main()

while(!q.empty())//

當佇列裡還有數存在時

}printf(

"%lld\n

",sum);

}return0;

}

哈弗曼編碼 哈弗曼樹

哈弗曼編碼是依賴於字元使用頻率來建立的一種編碼,通過把使用頻率低的字元分配相對較多的01編碼,而使用頻率高的分配相對較低的01編碼,來建立最小的帶權路徑長度的樹,來最大化的獲得編碼儲存空間的一種編碼規則。這個樹稱為哈弗曼樹,也稱為最優二叉樹。這樣可以確定每乙個字元的編碼不可能成為其他字元編碼的坐子串...

哈弗曼樹與哈弗曼編碼(實現)

歷史背景 1951年,霍夫曼在mit攻讀博士學位,他和修讀資訊理論課程的同學得選擇是完成學期報告還是期末考試。導師robert fano出的學期報告題目是 查詢最有效的二進位制編碼。由於無法證明哪個已有編碼是最有效的,霍夫曼放棄對已有編碼的研究,轉向新的探索,最終發現了基於有序頻率二叉樹編碼的想法,...

資料結構之哈弗曼樹與哈弗曼編碼

一.哈弗曼樹和哈弗曼編碼先知 哈弗曼樹是二叉樹中一種特殊的樹,也被稱為最優二叉樹。其通過某種規則 權值 來構造出一哈夫曼二叉樹,在這個二叉樹中,只有葉子節點才是有效的資料節點,其他的非葉子節點是為了構造出哈夫曼而引入的!哈夫曼編碼是通過哈夫曼樹進行的一種編碼,一般情況下,以字元 0 與 1 表示。編...