通过写这个编码和huffman树的构建,让我对huffman tree 有了更深的理解:
1:首先huffman是经过n-1次迭代之后生成的树,所以如果开始的节点有n个的话,那麽生成之后的的树的节点个数是2*n-1
2:编码的话可以用DFS处理;
3:树的节点新加了一个parents值,让我学到了一种新的写法。//在挑选最小值的时候需要
#include<iostream>
#include <iomanip>
#include <algorithm>
#include <string>
#include <map>
using namespace std;
struct element
{
char c=NULL;
int weight; // 权值域
int lchild, rchild, parent; // 该结点的左、右、双亲结点在数组中的下标
string code;
};
// 选取权值最小的两个结点
void selectMin(element a[],int n, int &s1, int &s2)
{ int i,j;
for ( i = 0; i < n; i++)
{
if (a[i].parent == -1)// 初始化s1,s1的双亲为-1
{
s1 = i;
break;
}
}
for (; i < n; i++)// s1为权值最小的下标
{
if (a[i].parent == -1 && a[s1].weight > a[i].weight)
s1 = i;
}
for (j = 0; j < n; j++)
{
if (a[j].parent == -1&&j!=s1)// 初始化s2,s2的双亲为-1
{
s2 = j;
break;
}
}
for (; j < n; j++)// s2为另一个权值最小的结点
{
if (a[j].parent == -1 && a[s2].weight > a[j].weight&&j != s1)
s2 = j;
}
}
// 哈夫曼算法
// n个叶子结点的权值保存在数组w中
void HuffmanTree(element huftree[], map<char,int> mp, int n)
{
for (int i = 0; i < 2*n-1; i++) // 初始化,所有结点均没有双亲和孩子
{
huftree[i].parent = -1;
huftree[i].lchild = -1;
huftree[i].rchild = -1;
}
int i=0;
for(map<char,int>::iterator iter=mp.begin();iter!=mp.end();iter++){
huftree[i].c=iter->first;
huftree[i].weight=iter->second;
i++;
}
for (int k = n; k < 2 * n - 1; k++) // n-1次合并
{
int i1, i2;
selectMin(huftree, k, i1, i2); // 查找权值最小的俩个根节点,下标为i1,i2
// 将i1,i2合并,且i1和i2的双亲为k
huftree[i1].parent = k;
huftree[i2].parent = k;
huftree[k].lchild = i1;
huftree[k].rchild = i2;
huftree[k].weight = huftree[i1].weight + huftree[i2].weight;
}
}
// 打印哈夫曼树
void print(element hT[],int n)
{
cout << "index weight parent lChild rChild char code" << endl;
cout << left; // 左对齐输出
for (int i = 0; i < n; ++i)
{
cout << setw(5) << i << " ";
cout << setw(6) << hT[i].weight << " ";
cout << setw(6) << hT[i].parent << " ";
cout << setw(6) << hT[i].lchild << " ";
cout << setw(6) << hT[i].rchild << " ";
cout << setw(6) << hT[i].c << " ";
cout << hT[i].code<<endl;
}
}
void encode(int index,element huftree[],string code){
huftree[index].code=code;
int l=huftree[index].lchild;
int r=huftree[index].rchild;
if(l!=-1){
encode(l,huftree,code+"0");
}
if(r!=-1){
encode(r,huftree,code+"1");
}
}
int main()
{
map<char,int> mp;
mp['A']=8;mp['B']=20;mp['C']=30;mp['D']=15;mp['E']=27;
int len=mp.size();
element *hufftree=new element[2*len-1]; // 动态创建数组
HuffmanTree(hufftree, mp, len);
encode(2*len-2,hufftree,"");
print(hufftree,2*mp.size()-1);
system("pause");
return 0;
}