数据结构与算法:哈夫曼树(源码)!
这些天明白了一个道理,搞技术也是需要激情的。
也不知道为什么这段过的感觉特别的不爽,也不知道是因为快要考试了,心里没底,而带来的恐惧,还是
搞技术太久,心里想放个假,总之是过的晕晕乎乎,做事情也总是反应迟钝,思维也不快,我爸妈说我是因为睡
不够,但是我觉得我一晚上睡6个半小时,也不算短了。真不知道这样的感觉还要持续多久。
习惯了,下课就做到电脑前,习惯了,晚上一个人回宿舍,习惯了,饿了随便吃点,习惯了,一个人钻研。
当一切开始成为了定式,总觉得生活变的简单。有一些人羡慕我,觉得我有很好的环境学技术。
但是我现在也不觉得我有什么好自满的东西。不过是个再普通不过的走在技术道路上的菜鸟。
心里有千万般的无奈,心里有数不清的彷徨。
我渴望曾经的激情。
其实我也不想说那么多,耽误看帖人的时间,但是心里总有些不吐不快。
师兄总是开玩笑的说我现在开始“淡定了”。
朋友们也觉得我越来越“沉默了”。
现在也不敢想以后会成什么样子,一切都未知。
我不想到了以后“生无可恋,死无可依”(这是一个老程序员的感悟)。
但是我不能停止,停止就是倒退。
好啦,不罗嗦了,下面是我的程序:
#define MAXVALUE 100000
using namespace std;
const int n=4;//叶子节点个数
//构造哈夫曼树结点
typedef struct{
int weight;//权值
int parent;//父节点
int lchild;//左子树
int rchild;//右子树
}HNodeType;
HNodeType HFMTree[2*n-1];//结点数
//构造哈夫曼编码数组
typedef struct{
int bit[n];
int start;
}HCodeType;
HCodeType HFMCode[n];
//创建哈夫曼树
void createHFMTree(HNodeType HFMTree[],int n){
int m1,x1,m2,x2;
int i,j;
//初始化
for(i=0;i<2*n-1;i++){
HFMTree[i].weight=0;
HFMTree[i].parent=-1;
HFMTree[i].lchild=-1;
HFMTree[i].rchild=-1;
}
cout<<"请输入结点权值:"<<endl;
for(i=0;i<n;i++){
cin>>HFMTree[i].weight;
}
for(i=0;i<n-1;i++){
x1=x2=MAXVALUE;
m1=m2=0;
for(j=0;j<n+i;j++){
if(HFMTree[j].parent==-1&&HFMTree[j].weight<x1){
x2=x1;
m2=m1;
x1=HFMTree[j].weight;
m1=j;
}
else if(HFMTree[j].parent==-1&&HFMTree[j].weight<x2){
x2=HFMTree[j].weight;
m2=j;
}
}
HFMTree[m1].parent=n+i;HFMTree[m2].parent=n+i;
HFMTree[n+i].weight=HFMTree[m1].weight+HFMTree[m2].weight;
HFMTree[n+i].lchild=m1;
HFMTree[n+i].rchild=m2;
}
}
//转化编码
void createHFMCode(HNodeType HFMTree[],HCodeType HFMCode[]){
HCodeType cd;
int i,j,c,p;
for(i=0;i<n;i++){
cd.start=n-1;
c=i;
p=HFMTree[c].parent;
while(p!=-1)
{
if(HFMTree[p].lchild==c)cd.bit[cd.start]=0;
else cd.bit[cd.start]=1;
cd.start--;
c=p;
p=HFMTree[c].parent;
}
for(j=cd.start+1;j<n;j++)
HFMCode[i].bit[j]=cd.bit[j];
HFMCode[i].start=cd.start+1;
}
}
//主函数
int main()
{
int i,j;
//创建树
createHFMTree(HFMTree,n);
//转码
createHFMCode(HFMTree,HFMCode);
cout<<endl;
for(i=0;i<n;i++)
{
for(j=HFMCode[i].start;j<=n-1;j++)
{
cout<<HFMCode[i].bit[j];
}
cout<<endl;
}
return 0;
}
这个是雏形,下面我们要实现的功能是,输入一个含有N位A,B,C,D四种字母的字符串。
然后转换成只含有0,1的代码串。之所以要使用哈夫曼树是因为哈夫曼树是最优树。根据权值来实现最短编码。
下面是实现自动转码的程序:
#define MAXVALUE 100000
using namespace std;
const int n=4;//叶子节点个数
string l;
int size;
//构造哈夫曼树结点
typedef struct{
int weight;//权值
int parent;//父节点
int lchild;//左子树
int rchild;//右子树
}HNodeType;
HNodeType HFMTree[2*n-1];//结点数
//构造哈夫曼编码数组
typedef struct{
int bit[n];
int start;
}HCodeType;
HCodeType HFMCode[n];
//创建哈夫曼树
void createHFMTree(HNodeType HFMTree[],int n){
int m1,x1,m2,x2;
int i,j;
//初始化
for(i=0;i<2*n-1;i++){
HFMTree[i].weight=0;
HFMTree[i].parent=-1;
HFMTree[i].lchild=-1;
HFMTree[i].rchild=-1;
}
cout<<"*******************哈夫曼树字符串最优转码程序***********************"<<endl;
cout<<"请输入一个字符串:(只含有A,B,C,D四种字符,输入回车结束)"<<endl;
cin>>l;
std::string str(l);
size=str.size();
for(int i=0;i<size;++i){
if(str.at(i)=='A')HFMTree[0].weight++;
else if(str.at(i)=='B')HFMTree[1].weight++;
else if(str.at(i)=='C')HFMTree[2].weight++;
else if(str.at(i)=='D')HFMTree[3].weight++;
else{
cout<<"输入有误!"<<endl;
break;
}
}
for(i=0;i<n-1;i++){
x1=x2=MAXVALUE;
m1=m2=0;
for(j=0;j<n+i;j++){
if(HFMTree[j].parent==-1&&HFMTree[j].weight<x1){
x2=x1;
m2=m1;
x1=HFMTree[j].weight;
m1=j;
}
else if(HFMTree[j].parent==-1&&HFMTree[j].weight<x2){
x2=HFMTree[j].weight;
m2=j;
}
}
HFMTree[m1].parent=n+i;HFMTree[m2].parent=n+i;
HFMTree[n+i].weight=HFMTree[m1].weight+HFMTree[m2].weight;
HFMTree[n+i].lchild=m1;
HFMTree[n+i].rchild=m2;
}
}
//转化编码
void createHFMCode(HNodeType HFMTree[],HCodeType HFMCode[]){
HCodeType cd;
int i,j,c,p;
for(i=0;i<n;i++){
cd.start=n-1;
c=i;
p=HFMTree[c].parent;
while(p!=-1)
{
if(HFMTree[p].lchild==c)cd.bit[cd.start]=0;
else cd.bit[cd.start]=1;
cd.start--;
c=p;
p=HFMTree[c].parent;
}
for(j=cd.start+1;j<n;j++)
HFMCode[i].bit[j]=cd.bit[j];
HFMCode[i].start=cd.start+1;
}
}
//主函数
int main()
{
int i,j;
//创建树
createHFMTree(HFMTree,n);
//转码
createHFMCode(HFMTree,HFMCode);
cout<<endl;
int k=65;
for(i=0;i<n;i++)
{
cout<<(char)k<<"的编码:";
for(j=HFMCode[i].start;j<=n-1;j++)
{
cout<<HFMCode[i].bit[j];
}
k++;
cout<<endl;
}
cout<<"转码后的字符串为:"<<endl;
std::string str(l);
size=str.size();
for(int i=0;i<size;++i){
if(str.at(i)=='A'){
for(j=HFMCode[0].start;j<=n-1;j++)
cout<<HFMCode[0].bit[j];
}
else if(str.at(i)=='B'){
for(j=HFMCode[1].start;j<=n-1;j++)
cout<<HFMCode[1].bit[j];
}
else if(str.at(i)=='C'){
for(j=HFMCode[2].start;j<=n-1;j++)
cout<<HFMCode[2].bit[j];
}
else if(str.at(i)=='D'){
for(j=HFMCode[3].start;j<=n-1;j++)
cout<<HFMCode[3].bit[j];
}
else{
cout<<"输入有误!"<<endl;
break;
}
}
return 0;
}
程序本机测试通过,可以放心运行!
转载注明:www.cnblogs.com/shiyangxt
作者:Steven(Steven's Think out)
出处:http://shiyangxt.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted on 2008-12-05 10:51 俱正Steven 阅读(11399) 评论(5) 编辑 收藏 举报