二元字首碼:任何字元的**不能作為其它字元**的字首.eg.q=不是二元字首**,如序列0100001會產生歧義
設c=是n個字元的集合,f(xi)為xi出現的頻率,d(xi)為xi的碼長,i=1,2,…,n.
儲存乙個字元的平均二進位制位數(碼數):
$b = \sum\limits_^f(x_i)d(x_i)$
每個二元字首碼對應一棵二叉樹,樹葉代表碼字,樹葉的深度表示碼長,平均二進位制位數相當於這棵樹在給定頻率下的平均深度,也稱為這棵樹的權
對同一組頻率可以構造出不同的二叉樹,對應的平均二進位制位數也不同。占用位數越少的壓縮效率越高,即每個碼字平均使用二進位制位數最少的字首碼,稱為最優二元字首碼
如果葉片數n=2k,且每個碼字的頻率是1/n,那麼這棵樹應是一顆均衡的二叉樹
問題:對於任意給定的n個頻率f(x1),f(x2),…,f(xn),如何構造一棵對應於最優二元字首碼的二叉樹?
huffman演算法:
輸入:c=字符集,每個字元的頻率f(xi),i=1,2,…,n.
輸出:q
1.n2.q
3.for i
4. z
5. z.left
6. z.right
7. f(z)
8. insert(q,z)
9.return q
版本一:(僅求帶權路徑長)
#include #include
using namespacestd;intmain()for (int i = 0; i < n; ++i)return 0;
版本二:(構造字首樹)
#include #include#include
using namespacestd;struct nodenode;和struct node{};的區別在於,後者內部可定義node變數
intfreq;
node*left;
node*right;
node():freq(0), left(null), right(null){}/*friend bool operator < (node a, node b)*/};classcmpvoid deletetree(node *a)void print(node *a)if (a->left)if (a->right)intmain();
priority_queueq;for (int i = 0; i < 10; ++i)
q.push(a[i]);for (int i = 0; i < 10; ++i){
a[i]=q.top();
q.pop();
cout<< a[i] << ' ';
輸出結果為:10 9 8 7 6 5 4 3 2 1
因此優先佇列中的元素採用指標
2)迴圈中使用new定義/賦值指標,都會重新申請記憶體(原本的依然存在),重定向指標
3)優先佇列兩種使用方法
方法一如之前**所示
方法二如下(我在「版本二」的注釋中試圖重現,但出了點小錯誤,有機會改吧……)
structnode{intx;inty;
friendbool operator
{return a.x > b.x; //結構體中,x小的優先順序高
priority_queue q; //定義方法
4)friend bool operator < (node *a, node *b)會報錯,過載運算子不能對指標單獨操作,因為系統已經定義了有關指標的運算,不能改變
5)**病,每行**的空格部分不能有中文空格和標點,否則會stray '\241' in program
二元最佳字首碼 最優字首編碼
字首編碼 在電文傳輸中,需要將電文 現的每個字元進行二進位制編碼。在設計編碼時需要遵守兩個原則 1 傳送方傳輸的二進位制編碼,到接收方解碼後必須具有唯一性,即解碼結果與傳送方傳送的電文完全一樣 2 傳送的二進位制編碼盡可能地短。下面我們介紹兩種編碼的方式。1 等長編碼 這種編碼方式的特點是每個字元的...
貪心演算法 最優字首碼
給定字符集c 和每個字元的頻率f xi 求關於c的乙個最優字首碼。構造最優字首碼的貪心演算法就是哈夫曼演算法 huffman 舉例 規則是 依次讀人檔案的二進位製碼,從哈夫曼樹的根結點出發,若當前讀入0,則走向左孩子,否則走向右孩子。include include include include u...
最優字首碼問題
構造最優字首碼的貪心演算法就是哈夫曼演算法 哈夫曼編碼 對於一顆具有n個葉子的哈夫曼樹,若對樹中的每個左分支賦予0,右分支賦予1,則從根到每個葉子的路徑上,各分支的賦值分別構成乙個二進位制串,該二進位制串就成為哈夫曼編碼。哈夫曼樹滿足兩條性質 性質證明如下 參考自 嚴蔚敏 資料結構教材 q c 頻率...