您的位置:首页 > 其它

My first blog in csdn!

2009-06-04 11:44 513 查看
//本程序演示了哈夫曼编码
//其基本原理为:将文件中的每个字符均转换为一个惟一的二进制串
//而每一个字符又可以用其权值(weight)来代替
//权值越大说明其出现的概率越大,则在哈夫曼二叉树中的位置越靠近根节点
//即其编码越短
//说明:其中每一个节点的权值(weight)=字符概率*100(即扩大了100倍)便于处理
//程序要求输入字符的个数(即哈夫曼树中叶节点的个数)和每一个叶节点的权值
]#include<iostream>
#include<vector>
using namespace std;
struct HuffNode
{
int weight;//权值
int lchild;//左孩子索引
int rchild;//右孩子索引值
int parent;//双亲索引值
};
HuffNode* initialize(int n)
{
HuffNode* hptr=new HuffNode[2*n];//下标为0的空间弃置不用,用于存储其他信息
int temp_1;
HuffNode* temp_2=hptr;
cout<<"Please input the value of the leaf node(weight):"<<endl;
for(int i=1;i<=n;++i)//输入叶子节点的权值
{
(*(temp_2+i)).lchild=0;
(*(temp_2+i)).rchild=0;
(*(temp_2+i)).parent=0;
cin>>temp_1;
(*(temp_2+i)).weight=temp_1;
}
for(i=n+1;i<=2*n-1;++i)//将除叶子节点外的节点lchild,rchild,parent,weight均初始化为0
{
(*(temp_2+i)).lchild=0;
(*(temp_2+i)).rchild=0;
(*(temp_2+i)).parent=0;
(*(temp_2+i)).weight=0;
}
cout<<endl;
cout<<"The inititial value: "<<endl;
for(i=1;i<=2*n-1;++i)
{
cout<<(*(hptr+i)).weight<<" "<<(*(hptr+i)).parent<<" "<<(*(hptr+i)).lchild<<" "<<(*(hptr+i)).rchild<<endl;
}
cout<<endl;
return hptr;
}
HuffNode* createHuffTree(HuffNode*hptr,int n)//n指的是叶子节点数目
{
HuffNode* temp=hptr;
int temp_weight_2,temp_weight,temp_child,k;
for(int i=n+1;i<=2*n-1;++i)//构造哈夫曼树
{
for(k=1;k<=i-1;++k)////寻找前i-1个节点中parent不为0的第一个节点的索引值和权值
{
temp_weight=(*(temp+k)).weight;
temp_child=k;
if((*(temp+k)).parent==0)
break;
}
for(k=k+1;k<=i-1;++k)//找到第一个最小值,同时找出权值最小时其所在索引号
{
if((*(temp+k)).parent==0)//parent为0的节点不在找最小值范围之内
{
if((*(temp+k)).weight<temp_weight)
{
temp_weight=(*(temp+k)).weight;
temp_child=k;
}
}
}

(*(temp+temp_child)).parent=i;//给第一个权值最小的节点的parent赋值
(*(temp+i)).lchild=temp_child;//作为父节点的左子树
for(k=1;k<=i-1;++k)//寻找前i-1个节点中parent不为0的第一个节点的索引值和权值
{
temp_weight_2=(*(temp+k)).weight;
temp_child=k;
if((*(temp+k)).parent==0)
break;
}
for(k=k+1;k<=i-1;++k)//找出第二个最小值,同时找出权值最小时其所在的索引号
{
if((*(temp+k)).parent==0)
{
if((*(temp+k)).weight<temp_weight_2)
{
temp_weight_2=(*(temp+k)).weight;
temp_child=k;
}
}
}
(*(temp+temp_child)).parent=i;//给第二个权值最小的节点的parent赋值
(*(temp+i)).weight=temp_weight+temp_weight_2;//构建第i个节点
(*(temp+i)).rchild=temp_child;//作为父节点的右子树
}
//just for display
cout<<endl;
cout<<"The HuffTree: "<<endl;
for(i=1;i<=2*n-1;++i)
{
cout<<(*(hptr+i)).weight<<" "<<(*(hptr+i)).parent<<" "<<(*(hptr+i)).lchild<<" "<<(*(hptr+i)).rchild<<endl;
}
cout<<endl;
return hptr;
}
void HuffEncode(vector<vector<int> >&v,HuffNode*hptr,int n)//哈夫曼编码(最佳编码法)
{
for(int i=1;i<=n;++i)
{
vector<int>temp;//temp向量用于临时存储01序列

int index=i;
do
{
if((*(hptr+(*(hptr+index)).parent)).lchild==index)//如果是父节点的左孩子则赋值为0
{
temp.push_back(0);
}
else if((*(hptr+(*(hptr+index)).parent)).rchild==index)//右孩子则赋值为1
{
temp.push_back(1);
}
index=(*(hptr+index)).parent;
}while(index!=0);
temp.push_back((*(hptr+i)).weight);//每一个向量第一个值为叶节点权值
v.push_back(temp);

}
}
void display(vector<vector<int> >v)
{
cout<<endl;
cout<<"The HuffEncode is: "<<endl;
for(int i=0;i<v.size();++i)
{
int temp=v[i].size();
for(int j=0;j<temp;++j)
{
cout<<v[i].back()<<" ";
v[i].pop_back();
}
cout<<endl;
}
}
int main()
{
vector<vector<int> >encode;
int leaf_num;
cout<<"Please input the number of the leaf nodes: ";
cin>>leaf_num;
HuffNode* hptr=initialize(leaf_num);
hptr=createHuffTree(hptr,leaf_num);
HuffEncode(encode,hptr,leaf_num);
display(encode);
cout<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: