採用貪心演算法來實現霍夫曼編碼。
首先輸入帯權值節點個數構造霍夫曼樹,再利用貪心演算法對節點進行編碼,在對哈夫曼樹編碼的過程中,先對權值較大的節點進行編碼,在編碼的過程中它們的字首中不能與其他已經編碼過的節點相同,這樣是為了在解碼的過程中更加容易;霍夫曼編碼的具體過程為採取可變長編碼方式,對檔案中出現次數多的字元採取比較短的編碼,對於出現次數少的字元採取比較長的編碼,可以有效地減小總的編碼長度。
例如,在英文中,e的出現頻率最高,z的出現頻率最低,所以可以用最短的編碼來表示e,用最長的編碼表示z。
演算法:輸入是沒有相同元素的字元陣列(長度n)以及字元出現的頻率,輸出是哈夫曼樹。
即假設有n個字元,則構造出得哈夫曼樹有n個葉子結點。n個字元的權值(頻率)分別設為w1,w2,…,wn,則哈夫曼樹的構造規則為:
1)將w1,w2,…,wn看成是有n棵樹的森林(每棵樹僅有乙個結點);
2)在森林中選出兩個根結點的權值最小的樹合併,作為一棵新樹的左、右子樹,且新樹的根結點權值為其左、右子樹根結點權值之和;
3)從森林中刪除選取的兩棵樹,並將新樹加入森林;
4)重複(2)、(3)步,直到森林中只剩一棵樹為止,該樹即為所求得的哈夫曼樹;
1)從樹根開始在hftree裡查詢w,向左走記為0;
2)向右走記為0,最終的01串就是w的編碼;
3)演算法思想類似於二叉樹的非遞迴遍歷演算法;
4)利用棧來存放上乙個樹節點的資訊;
#include #include #include typedef struct
htnode, *huffmantree; //動態分配陣列,儲存哈夫曼樹
typedef char *huffmancode; //動態分配陣列,儲存哈夫曼編碼
//選擇兩個parent為0,且weight最小的結點s1和s2
void select(huffmantree *ht,int n,int *s1,int *s2)
}for(i=1; i<=n; i++)
}*s1=min;
for(i=1; i<=n; i++)
}for(i=1; i<=n; i++)
}*s2=min;
}//構造哈夫曼樹ht,w存放已知的n個權值
void crthuffmantree(huffmantree *ht,int *w,int n)
for(i=n+1; i<=m; i++) //非葉子結點的初始化
printf("\n哈夫曼樹為: \n");
for(i=n+1; i<=m; i++) //建立非葉子結點,建哈夫曼樹
printf("\n");
}//從葉子結點到根,逆向求每個葉子結點對應的哈夫曼編碼
void crthuffmancode(huffmantree *ht, huffmancode *hc, int n)
else
}hc[i]=(char *)malloc((n-start)*sizeof(char)); //為第i個編碼分配空間
strcpy(hc[i],&cd[start]); //將cd複製編碼到hc
}free(cd);
for(i=1; i<=n; i++)
printf(" 權值為%d的哈夫曼編碼為:%s\n",(*ht)[i].weight,hc[i]);
for(i=1; i<=n; i++)
w+=(*ht)[i].weight*a[i];
printf(" 帶權路徑為:%d\n",w);
霍夫曼編碼的時間演算法複雜度為:o(nlogn);
(1)哈夫曼編碼的平均碼長要比等長編碼短。由此操作碼得以優化。
(2)哈夫曼二叉樹的構造為左1右0。
(3)因程式中權值設定為整型,故若輸入權值中有小數,請經所有數乘以10^n倍,將其轉換成整型集合。
哈夫曼編碼演算法:每次將集合中兩個權值最小的二叉樹合併成一棵新二叉樹,n-1次合併後,成為最終的一棵哈夫曼樹。這既是貪心法的思想:從某乙個最初狀態出發,根據當前的區域性最優策略,以滿足約束方程為條件,以使目標函式最快(或最慢)為原則,在候選集合中進行一系列的選擇,以便盡快構成問題的可行解。每次選擇兩個權值最小的二叉樹時,規定了較小的為左子樹。
貪心演算法實現霍夫曼編譯碼
霍夫曼編碼是一種被廣泛應用而且非常有效的資料壓縮技術,根據待壓縮資料的特徵,乙個可壓縮掉20 90 這裡考慮的資料指的是字串序列。要理解霍夫曼編碼,先要理解霍夫曼樹,即最優二叉樹,是一類帶權路徑長度最短的樹。路徑是指從樹中乙個結點到另乙個結點之間的通路,路徑上的分支數目稱為路徑長度。樹的路徑長度是從...
貪心演算法 Huffman編碼
huffman編碼是資料壓縮常見的壓縮方法。即將不同概率出現的字元以不同長度的二進位制位進行編碼,概率出現的越高的字元使用長度越短的編碼,概率出現越低的字元使用長度越長的編碼。下面是對儲存字元出現概率的檔案charactorsheet.txt,每一行的左邊是字元出現的概率,單位是0.01,右邊是要編...
演算法導論 貪心演算法之赫夫曼編碼
討論赫夫曼編碼問題,赫夫曼編碼的思想就是變長編碼。變長編碼就是讓字元表中出現概率高的字元的編碼長度盡可能小,而出現概率高的字元的編碼長度相對較長。然後還要遵循字首碼的要求,就是任意乙個編碼都不是其他編碼的字首碼,這樣方便解碼。對於下表中的字元和相應的出現概率,有對應圖中的編碼樹 可以比較容易的看出來...