赫夫曼樹,又稱最優樹,是一類帶權路徑長度最短的樹。
首先給出路徑和路徑長度的概念。從樹中乙個節點到另乙個節點之間的分支構成這兩個節點之間的路徑,路徑上的分支數目叫做路徑長度。樹的路徑長度是從樹根到每一節點的路徑長度之和。
考慮上帶權的節點。節點的帶權路徑長度為從該結點到樹根之間的路徑長度與節點上權的乘積。樹的帶權路徑長度為樹中所有葉子節點的帶權路徑長度之和,通常記作wpl=∑n
k=0 wklk 。
舉個例子,如下圖
上圖中的樹不是赫夫曼樹,由7,5,2,4構成的赫夫曼樹如圖所示
按照上面的赫夫曼樹,我們將在父節點左邊的路徑用0表示,右邊的用1表示。由此得到
a (0)
b (10)
c (110)
d (111)
這樣的二進位制編碼我們稱為赫夫曼編碼。
1.根據給定的n個權值構成n棵二叉樹的合集f。(每棵二叉樹的左右子樹為空)
2.在f中選取兩棵根結點的權值最小的樹作為左右子樹構造一棵新的二叉樹,且置新的二叉樹的根結點的權值為其左右子樹上根結點的權值之和。
3.在f中刪除這兩棵樹,同時將新得到的二叉樹加入f中。
4.重複步驟2和步驟3,直到f中只剩一棵樹為指。這棵樹便是赫夫曼樹。
#include
#include
#include
#include
typedef
struct tree //建立乙個樹結構
hafftree;
void createhafftree(int* weight,int n,hafftree* phafftree) //建立赫夫曼樹
for(i=0;i1;++i)
else
if(phafftree[j].weight0)
}phafftree[x1].flag=1;
phafftree[x2].flag=1;
phafftree[x1].parent=phafftree[x2].parent=n+i;
phafftree[n+i].weight=min1+min2;
phafftree[n+i].left=x1;
phafftree[n+i].right=x2;
}}void haffcode(hafftree* phafftree,int n,char*** code) //根據赫夫曼樹求赫夫曼碼,由葉子到根求赫夫曼編碼,因此start--
len=strlen(ch+start+1)+1;
(*code)[i]=(char*)malloc(len);
strcpy((*code)[i],ch+start+1);
}}void main()
; int n=sizeof(weight)/sizeof(int);
hafftree* phafftree=(hafftree*)malloc(sizeof(hafftree)*(2*n-1)); //有n個葉子節點,因此總節點個數為2n-1
createhafftree(weight,n,phafftree);
char** code=null;
haffcode(phafftree,n,&code);
for(int i=0;iprintf("%d ",weight[i]);
puts(code[i]);}}
看看結果吧
和根據赫夫曼樹中推出的結果一樣。
赫夫曼樹與赫夫曼編碼
問題描述 利用huffman編碼進行通訊可以大大提高通道利用率,縮短資訊傳輸時間,降低傳輸成本。但是,這要求在傳送端通過乙個編碼系統對待傳資料預先編碼,在接受端將傳來的資料編碼進行解碼 復原 對於有些通道,每端都需要乙個完整的編 解碼系統。試為這樣的資訊收發站編寫乙個huffman的編 解碼系統。給...
赫夫曼樹和赫夫曼編碼
赫夫曼樹 1 先把有權值的葉子節點按照從小到大的順序排成乙個有序序列,即 a 5 e 10 b 15 d 30 c 40 2 取前兩個權值最小的結點即a 5 和e 10 作為乙個新的結點n1的兩個子節點,結點權值較小的作為左結點,即a為左結點,e為右結點,n1的權值為兩個結點權值的和,即5 10 1...
赫夫曼樹和赫夫曼編碼
include define maxsize 128 字元表 typedef struct table 哈夫曼樹節點 typedef struct hfmtree 哈夫曼編碼 typedef struct hfmcode hfmtree hdata 2 maxsize 1 hfmcode code ...