数据结构与算法:哈夫曼树(源码)!

这些天明白了一个道理,搞技术也是需要激情的。

也不知道为什么这段过的感觉特别的不爽,也不知道是因为快要考试了,心里没底,而带来的恐惧,还是

搞技术太久,心里想放个假,总之是过的晕晕乎乎,做事情也总是反应迟钝,思维也不快,我爸妈说我是因为睡

不够,但是我觉得我一晚上睡6个半小时,也不算短了。真不知道这样的感觉还要持续多久。

习惯了,下课就做到电脑前,习惯了,晚上一个人回宿舍,习惯了,饿了随便吃点,习惯了,一个人钻研。

当一切开始成为了定式,总觉得生活变的简单。有一些人羡慕我,觉得我有很好的环境学技术。

但是我现在也不觉得我有什么好自满的东西。不过是个再普通不过的走在技术道路上的菜鸟。

心里有千万般的无奈,心里有数不清的彷徨。

我渴望曾经的激情。

其实我也不想说那么多,耽误看帖人的时间,但是心里总有些不吐不快。

师兄总是开玩笑的说我现在开始“淡定了”。

朋友们也觉得我越来越“沉默了”。

现在也不敢想以后会成什么样子,一切都未知。

我不想到了以后“生无可恋,死无可依”(这是一个老程序员的感悟)。

但是我不能停止,停止就是倒退。

好啦,不罗嗦了,下面是我的程序:

 

#include<iostream> 
#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的代码串。之所以要使用哈夫曼树是因为哈夫曼树是最优树。根据权值来实现最短编码。

下面是实现自动转码的程序:

 

#include<iostream> 
#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

 

posted on 2008-12-05 10:51  施杨  阅读(11390)  评论(5编辑  收藏  举报

导航