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

原文出处:http://www.cnblogs.com/shiyangxt/archive/2008/12/05/1348174.html

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

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

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

不够,但是我觉得我一晚上睡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;

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值