哈夫曼樹 資料結構課程
阿新 • • 發佈:2021-11-10
讓使用頻率高的(權值高)節點離根部更近,生成一個哈夫曼樹。
具體演算法為:1輸入各節點權重,把每一個節點當成一課子樹,從而得到一片森林
2從森林中尋找權值最小的兩棵樹,把他們合併為一課新的樹,樹的權值為原來這兩棵子樹的權值之和
3不斷進行第二步,直到把森林合併為一個樹時停止
這樣就可以生成一棵哈夫曼樹,然後每個葉節點向根部回溯,根據節點來自左右子樹編碼0/1,到達根節點時就得到了每個葉節點的哈夫曼編碼。
舉個栗子: 輸入四個節點,權重分別為1,2,3,4.
step1:權值最小的兩個子樹為,1,2 把他們合併為權值為3的樹 (此時,森林為3,3,4)
step2:權值最小的兩個子樹為,3,3 把他們合併為權值為6的樹 (此時森林為6,4)
step3:權值最小的兩個子樹為,6,4 把他們合併為權值為10的樹 (此時森林為10,只有一棵樹)
這樣就得到了哈夫曼樹。如圖。
#include<cstdio> #include<cstring> #include<malloc.h> #include<iostream> using namespace std; const int N=100; typedef struct//節點型別 { char data; int weight; int parent; int lchild; int rchild; }HTNode,生成哈夫曼樹及哈夫曼編碼*HuffmanTree; typedef struct//哈夫曼編碼型別 { char bit[N]; int start; }HCode_Node; void CreateHTCode(HTNode HTree[],HCode_Node HCode[],int n) { int i,f,c; HCode_Node hc; for(i=1;i<=n;i++) { hc.start=n; c=i; f=HTree[i].parent; while(f)//對每個節點通過迭代尋找父節點 編碼哈夫曼編碼{ if(HTree[f].lchild==c) hc.bit[--hc.start]='0'; else hc.bit[--hc.start]='1'; c=f; f=HTree[f].parent; } HCode[i]=hc; } } void DisplayHuffmanCode(HTNode HTree[],HCode_Node HCode[],int n) { int i,k; printf(" 輸出哈夫曼編碼\n"); for(i=1;i<=n;i++) { //printf("start ==%d\n",HCode[i].start); for(k=0;k<HCode[i].start;k++) printf(" "); for(k=HCode[i].start;k<n;k++) printf("%c",HCode[i].bit[k]); printf("\n"); } } void Select(HuffmanTree &HT,int len,int &s1,int &s2) { int i,min1=0xffff,min2=0xffff; for(i=1;i<=len;i++) { if(!HT[i].parent) { if(HT[i].weight <min1) { min2=min1;s2=s1; min1=HT[i].weight;s1=i; }else if(HT[i].weight <min2) { min2=HT[i].weight ;s2=i; } } } return; } void CreatHuffmanTree(HuffmanTree &HT,int n) { int m,s1,s2,i; if(n<=1) return ; m=n*2-1; HT= new HTNode[m+1];//申請空間 for(i=1;i<=m;i++) HT[i].parent=HT[i].lchild=HT[i].rchild=0;//初始化變數 printf("請輸入各節點的權值\n"); for(i=1;i<=n;i++) scanf("%d",&HT[i].weight); //開始構造 for(i=n+1;i<=m;i++) { Select(HT,i-1,s1,s2);//尋找權值最小的子樹 HT[s1].parent=i; HT[s2].parent=i; //合併權值最小的子樹 HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight =HT[s1].weight+HT[s2].weight; } HCode_Node HCode[N];//建立哈夫曼編碼的陣列 CreateHTCode(HT,HCode,n); DisplayHuffmanCode(HT,HCode,n); return; } int main() { HuffmanTree HT;int n; printf("請輸入節點個數\n"); scanf("%d",&n); CreatHuffmanTree(HT,n); return 0; }