問題描述:
如果我們有乙個10萬個字元的資料檔案。每個字元出現的頻率不同,現在我們要用最少的空間儲存資料,也就是將這10萬個資料進行編碼,得到最優編碼序列。
問題分析:
一般的編碼有定長編碼和不定長編碼,如果採用定長編碼,如果字元檔案一共有6個字元,那麼定長編碼乙個字元的長度為3(二進位制編碼),10萬個字元編碼需要30萬個位元組空間,如果字元檔案的字元種類更多,隨著字元種類的增加,需要的位元組空間爆漲,顯然不符合我們的最優編碼序列,分析問題,我們需要解決兩個問題。1.編碼盡可能短。2.不能有二義性。什麼是二義性?比如a:0,b:1,c:11,現在給你乙個序列0111,這個序列是表示abc,還是abbb?,這裡我們考慮字首碼,既沒有任何碼字是其他碼字的字首,與任何字元編碼相比,字首碼可以保證最優的資料壓縮率。
資料結構:
哈夫曼編碼的基本思想是按照字元的頻率構造一顆哈夫曼樹,頻率越高的字元,離根節點越近,並且規定位於節點左邊的左孩子跟他父節點的邊的權值為0,右邊的為1,構造哈夫曼的過程是選取兩個節點沒有雙親並且權值最小的作為左右子樹。
**:#include
#include
#include
using namespace std;
#define maxbit 100
#define maxvalue 10000
#define maxleaf 30
#define maxnode 2*maxleaf-1
typedef struct
huffnodetype;
typedef struct
huffcodetype;
huffnodetype huffnode[maxnode];
huffcodetype huffcode[maxleaf];
//構造赫夫曼樹
void huffmantree(huffnodetype huffnode[maxnode], int n)
//輸入葉子節點的權值
for (i = 0; i < n; i++)
//構造赫夫曼樹
for (i = 0; i < n-1; i++)//n-1次合併
else if (huffnode[j].weigth < m2&&huffnode[j].parent== -1)
}//合併
huffnode[x1].parent = n + i;//n+i為新開節點的編號
huffnode[x2].parent = n + i;
huffnode[n + i].weigth = m1 + m2;
huffnode[n + i].lchild = x1;
huffnode[n + i].rchild = x2;}}
//赫夫曼樹編碼
void huffmancode(huffcodetype huffcode[maxleaf], int n)
else
cd.start--;
c = p;
p = huffnode[c].parent;
}for (j = cd.start + 1; j < n; j++)
huffcode[i].start = cd.start;}}
int main()
cout << endl;
}//system("pause");
return 0;
}
哈夫曼編碼 哈夫曼樹
1.定義 哈夫曼編碼主要用於資料壓縮。哈夫曼編碼是一種可變長編碼。該編碼將出現頻率高的字元,使用短編碼 將出現頻率低的字元,使用長編碼。變長編碼的主要問題是,必須實現非字首編碼,即在乙個字符集中,任何乙個字元的編碼都不是另乙個字元編碼的字首。如 0 10就是非字首編碼,而0 01不是非字首編碼。2....
哈夫曼樹 哈夫曼編碼
定義從a結點到b結點所經過的分支序列為從a結點到b結點的路徑 定義從a結點到b結點所進過的分支個數為從a結點到b結點的路徑長度 從二叉樹的根結點到二叉樹中所有結點的路徑長度紙盒為該二叉樹的路徑長度 huffman樹 帶權值路徑長度最小的擴充二叉樹應是權值大的外界點舉例根結點最近的擴充二叉樹,該樹即為...
哈夫曼編碼 哈夫曼樹
哈夫曼樹是乙個利用權值進行優化編碼的乙個比較奇怪的樹,他的實現比較簡單,用途也比較單一。哈夫曼樹的實現,實現要求 通過哈夫曼樹可以保證在編碼過程中不會出現例如 1000和100這樣的編碼規則,否則就會編碼失敗,因為1000和100在某些情況下的編碼會一模一樣。通過哈夫曼樹可以保證權值大的值進行編碼時...