1. 程式人生 > 其它 >哈夫曼樹 資料結構課程

哈夫曼樹 資料結構課程

讓使用頻率高的(權值高)節點離根部更近,生成一個哈夫曼樹。

具體演算法為: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; }
生成哈夫曼樹及哈夫曼編碼