哈夫曼編譯碼演算法(C實現)

2021-08-05 21:39:10 字數 3778 閱讀 4557

記得在畢業前去找工作,應聘康佳集團移動應用工程師的筆試題出了這麼一道題。

傳輸文字字元」badcadfeed」,只能出現」abcdef」這六個字元,使用以下的編碼方式:

如傳輸字元:badcadfeed          接收編碼:001000011010000011101100100011

接收方可以根據每3個bit進行一次字元解碼的方式還原文字傳輸的資訊,但是這樣的傳輸效率太低了,需要30bit才傳送10個字元。如何編碼來提高傳輸以及接收效率???請寫出你的編碼方式以及演算法思想。

我當時並沒有想到解決方法,gg了。最近運用到霍夫曼樹,現在回想起來不就是這個演算法嗎,哈哈哈,太好了。在這裡總結一下。

引入:要提高效率,必須要從編碼方式去改變,這是無疑的。這裡運用了避免每乙個字元都占有相同的bit位。如

如傳輸字元:badcadfeed          接收編碼:1001010010101001000111100 

改進編碼方式之後,可以看到傳送相同的字元,需要25bit位就可以表示10個字元了。這種編碼明顯是有很大優勢的。

問題:這個編碼方式有什麼規律呢?

怎麼得到呢?又是如何在接收方解碼的呢?下面來揭開神奇的面紗。

假定經過統計得出abcdef在所需傳輸報文出現的概率如下:

霍夫曼樹演算法: 

給定實數w1,w2,···,wt且 w1<=w2<=···<=wt           

(1)連線w1,w2為權的兩片樹葉,得一分支點,其權為w1+w2 ;

(2)在w1+w2, w3+···+wt中選出兩個最小的權,連線它們對應的頂點(不一定都是樹葉),得分支點及所帶的權;

(3)重複(2),直到形成t – 1個分支點,t片樹葉為止

或者這樣描述演算法:

1、給定n個數值

2.根據這n個數值構造二叉樹集合f

f =            ti的資料域為vi,左右子樹為空

3.在f中選取兩棵根結點的值最小的樹作為左右子樹構造一棵新的二叉樹,這棵二叉樹的根結點中的值為左右子樹根結點中的值之和

4.在f中刪除這兩棵子樹,並將構造的新二叉樹加入f中

5.重複3和4,直到f中只剩下乙個樹為止。這棵樹即霍夫曼樹

**上面演算法過程:(不想用電腦畫圖了,直接簡單粗暴用手畫乙個)

huffman樹中,左邊分支置為0,右邊分支置為1,就行形成了每個結點的哈夫曼編碼了

哈夫曼樹的應用:

主要用途是實現資料壓縮。在某些通訊場合,需將傳送的文字轉換成由二進位制字元組成的字串進行傳輸,也是現代壓縮軟體中運用到的演算法的基礎

測試結果:

c實現**:

// huffman.h

#ifndef huffmanbitree_h_h

#define huffmanbitree_h_h

//資料封裝

typedef int leafnode;

// 哈夫曼樹結點結構體

typedef struct huffmantree

huffmannode;

//建立哈夫曼樹

huffmannode* createhuffmantree(int* arr, int n);

//列印哈夫曼樹

void printhuffmantree(huffmannode* hufmtree);

// 哈夫曼編碼

void huffmancode(huffmannode* hufmtree, int depth); // depth是哈夫曼樹的深度

//哈夫曼解碼

void huffmandecode(char decodestr, huffmannode* hufmtree, char nodestr); // decodestr是要解碼的01串,nodestr是結點對應的字元

#endif

#include #include #include #include "huffman.h"

// 構建哈夫曼樹

huffmannode* createhuffmantree(int* arr, int n)

for (i=0; iweight < total_huffmannode[firstsmall]->weight)

else if (total_huffmannode[j]->weight < total_huffmannode[secondsmall]->weight)

} }

hufmtree = (huffmannode*)malloc(sizeof(huffmannode));

hufmtree->weight = total_huffmannode[firstsmall]->weight + total_huffmannode[secondsmall]->weight;

hufmtree->lchild = total_huffmannode[firstsmall];

hufmtree->rchild = total_huffmannode[secondsmall];

total_huffmannode[firstsmall] = hufmtree;

total_huffmannode[secondsmall] = null;

} free(total_huffmannode);

return hufmtree;

}

// 列印哈夫曼樹

void printhuffmantree(huffmannode* hufmtree)

} }

// 遞迴進行哈夫曼編碼

void huffmancode(huffmannode* hufmtree, int depth) // depth是哈夫曼樹的深度

} }

// 哈夫曼解碼

void huffmandecode(char decodestr, huffmannode* hufmtree, char nodestr) // decodestr是要解碼的01串,nodestr是結點對應的字元

else

++i;

} printf("%c", nodestr[total_huffmannodetree->index]); // 輸出解碼後對應結點的字元

} }

}

#include #include #include #include "huffman.h"  

int main()  

int* arrleafnode_weight;  

arrleafnode_weight=(int*)malloc(n*sizeof(leafnode));  

printf("請輸入%d個結點的權值:\n", n);  

for (i=0; i

c實現哈夫曼編譯碼系統

1 問題描述 利用哈夫曼編碼進行通訊可以大大提高通道利用率,縮短資訊傳輸時間,降低傳輸成本。但是,這要求在傳送端通過乙個編碼系統對待傳資料預先編碼,在接收端將傳來的資料進行解碼 解碼 對於雙工通道 即可以雙向傳輸資訊的通道 每端都需要乙個完整的編 解碼系統。試為這樣的資訊收發站設計乙個哈夫曼編譯碼系...

哈夫曼樹編 解碼演算法

一 實驗目的 掌握哈弗曼編 解碼演算法。1.掌握huffman 樹的概念 特點和儲存結構 2.掌握huffman 樹的構造方法 3.學會靈活運用huffman 樹解決編碼問題。4.問題描述 5.某報文中共出現n個字元,各字元出現頻度依次為w1,w2,wn。要求設計乙個不等長的編碼方案,輸出每個字元對...

哈夫曼樹以及編譯碼

這一篇要總結的是樹中的最後一種,即哈夫曼樹,我想從以下幾點對其進行總結 1,什麼是哈夫曼樹?2,如何構建哈夫曼樹?3,哈夫曼編碼?4,演算法實現?回到頂部 什麼是哈夫曼樹呢?哈夫曼樹是一種帶權路徑長度最短的二叉樹,也稱為最優二叉樹。下面用一幅圖來說明。它們的帶權路徑長度分別為 圖a wpl 5 2 ...