【數據結構】二叉樹的一個應用,哈夫曼編碼的生成

1.哈夫曼樹只有結點爲0.或者結點爲2的值。所以如果葉子結點爲n的話,那麼整個哈夫曼樹的所有結點個數爲2n-1;因爲結點爲2的結點個數n0=n2+1;所以總數n=n0+n2=2n0-1;

  

過程:<1>由已知的n個權值形成哈夫曼樹的初態,即在數組ht[]的前n項中填入相應的權值。

           <2>建立哈夫曼樹。依次將數組ht[]中的第n+1項到第m項作爲當前項,並進行以下處理:

                      1.在前已形成的項目中選擇兩個權值最小且無雙親的項。

                      2.將當前項的序號填入兩個選擇的項作爲雙親,將兩個選擇項的序號填入當前項分別作爲左右孩子。

                      3.將兩個選擇項的權值相加後填入當前項作爲當前項的權值。

           <3>由已形成的哈夫曼樹求哈夫曼編碼。對每個葉節點都進行如下處理:

             掃描由葉節點到根節點的各條分支,若果分支中的當前結點與雙親關係是左支關係,則生成編碼0,若分之中的當前結點與雙親結點是右支關係,則生成編碼1,由此生成的二級制碼的序列即爲該結點的哈夫曼編碼。

程序如下:

#include<iostream>
using namespace std;
#define maxlen 100
struct HaffNode
{
int weight;
int parent;
int lchild;
int rchild;
};
struct HaffCode
{
int bit[maxlen];
int start;
int weight;
};
void Haffman(int w[],int n,HaffNode ht[], HaffCode hc[])
{
int i, j, m1, m2, x1, x2;//m1,m2分別表示最小,次小的權值;x1,x2分別表示當前分支結點的左右兒子
//步驟1.構造哈夫曼樹
for (i = 0; i < 2 * n - 1; i++)//哈夫曼樹初始化
{
if (i < n)ht[i].weight = w[i];
else
ht[i].weight = 0;
ht[i].parent = 0;
ht[i].lchild = ht[i].rchild = -1;
}
for (i = 0; i < n - 1; i++)//構造哈夫曼樹的n-1個分支結點
{
m1 = m2 = 1000;
x1 = x2 = 0;
for (j = 0; j < n + i; j++)
{
if (ht[j].weight < m1 && ht[j].parent == 0)
{
m2 = m1;//最小保存到次小
x2 = x1;
m1 = ht[j].weight;
x1 = j;
}
else if (ht[j].weight < m2 && ht[j].parent == 0)
{
m2 = ht[j].weight;
x2 = j;
}
}
ht[x1].parent = n + i;
ht[x2].parent = n + i;
ht[n + i].weight = ht[x1].weight + ht[x2].weight;
ht[n + i].lchild = x1;
ht[n + i].rchild = x2;
}
//步驟2 由哈夫曼樹生成哈夫曼編碼
HaffCode cd;
int child, parent;
for (i = 0; i < n; i++)//由哈夫曼樹生成哈夫曼編碼
{
cd.start = n - 1;
cd.weight = ht[i].weight;
child = i;
parent = ht[child].parent;
while (parent != 0)
{
if (ht[parent].lchild == child)
cd.bit[cd.start] = 0;
else
cd.bit[cd.start] = 1;
cd.start--;
child = parent;
parent = ht[child].parent;
}
for (j = cd.start + 1; j < n; j++)
hc[i].bit[j] = cd.bit[j];
hc[i].start = cd.start;
hc[i].weight = cd.weight;
}


}
int main(void)
{
int w[] = { 4, 2, 6, 8, 3, 2, 1 };
int n = 7, i, j;
HaffNode *ht = new HaffNode[2 * n - 1];
HaffCode *hc = new HaffCode[n];
Haffman(w, n,ht, hc);
for (i = 0; i < n; i++)
{
cout << "weight=" << hc[i].weight << "code=";
for (j = hc[i].start + 1; j < n; j++)
cout << hc[i].bit[j];
  cout << endl;
}
}

效果圖:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章