給出n個字元的頻率,給每個字元賦予乙個01編碼串,使得任意乙個字元的編碼不是另乙個字元編碼的字首,而且編碼後總長度(每個字元的頻率與編碼長度乘積的總和)盡量小。
哈夫曼演算法
第一步:初始化n個單節點的樹,並為它們標上字母表中的字元。把每個字元的概率記在樹的根中,用來指出樹的權重(更一般地來說,樹的權重等於樹中所有葉子的概率之和)。
第二步:重複下面的步驟,直到只剩一棵單獨的樹。找到兩棵權重最小的樹(對於權重相同的樹,可任意選擇其一)。把它們作為新樹中的左右子樹,並把其權重之和作為新的權重記錄在新樹的根中。
例:n=7,概率:1/10,1/10,1/10,1/10,1/10,2/10,3/10
為計算簡便,只取分子,即1,1,1,1,1,2,3
權重:(1+1)*4+(1+1+1)*3+(2+3)*2/10=2.7
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const
int inf =
0x3f3f3f3f
;priority_queue
, greater
>q;
ll n, ans =
0, t, x, y;
intmain()
while
(!q.
empty()
)printf
("%lld"
, ans)
;}
主要時間複雜度在優先佇列插入元素排序,所以時間複雜度為:
github原始碼位址
作業11 最優字首碼
問題 給定字符集 c 和每個字元的頻率f xi 求關於 c 的乙個最優字首碼。構造最優字首碼的貪心演算法就是哈夫曼演算法 huffman 哈夫曼樹的基本思想 選擇權值小的葉子離根距離遠些。實現 第一步 以每個結點作為根,構造只有乙個根結點的n棵二叉樹,根的權值就是結點的權。第二步 在所有二叉樹中選擇...
作業11 最優字首碼
哈夫曼編碼 兩個結構體,a用來儲存樹節點 b儲存節點鍊錶 輸入資料儲存到a結構體指標陣列,隨後按照權值排序 1 將陣列中的指標插入到b結構體組成的鍊錶中 2 取煉表前兩個節點的a元素,合併成新的乙個b,構成乙個新的b節點c,將c公升序插入到鍊錶中 3 煉表頭結點右移兩位 重複1,2,3操作直到鍊錶中...
演算法 作業11 最優字首編碼(哈夫曼樹及編碼)
給定字符集c 和每個字元的頻率f xi 求關於c的乙個最優字首碼。哈夫曼演算法 1 初始化n個單節點的樹,每個字元的概率記在樹的根中,用作樹的權重。2 找到兩棵權重最小的樹,把它們作為新樹中的左右子樹,並把權重和記作新的權重記錄在新樹的根中。3 重複第二步直到只剩一顆單獨的樹。huffman演算法 ...