CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

哈夫曼树的问题?

楼主yuucyf(天赐)2006-03-04 13:51:52 在 C/C++ / C语言 提问

以下是哈夫曼树的代码,但是有点错误,是逻辑错误,运行后不正确,不知道为什么?  
  找了好久找不到错误的所在,所以请大家帮帮忙!!!!  
  谢谢!!!!  
  代码如下:  
   
   
  #include<iostream>  
  #include<stdlib.h>  
  using   namespace   std   ;  
   
  const   float   MaxValue   =   2.0     ;                   //初始设定的权值最大值    
  const   int   MaxBit   =   10   ;                               //初始设定的最大编码位数    
  const     int   MaxN   =   20   ;                                 //初始设定的最大结点个数    
   
   
  //哈夫曼数的结点结构    
  struct   HaffNode  
  {  
        float   weight     ;                             //权值    
        int   flag     ;                                     //标记    
        int   parent   ;                                   //双亲结点下标    
        int   leftchild   ;                             //左孩子下标    
        int   rightchild   ;                           //右孩子下标    
  }     ;  
   
   
  //存放哈夫曼编码的数组元素结构    
  struct   Code  
  {  
        int   bit[MaxN]     ;                           //数组    
        int   start     ;                                   //编码的起始下标    
        float   weight   ;                               //字符的权值    
  }     ;  
   
   
  //建立叶结点个数为n权值数组为weight的哈夫曼树haffTree    
  void     Haffman(float   weight[]   ,   int   n   ,   HaffNode   haffTree[])  
  {  
      int   j   ,   x1   ,   x2   ;  
      float   m1   ,   m2     ;  
       
      //哈夫曼树haffTree[]初始化。n个叶结点共有2n-1个结点    
      for(int   i   =   0   ;   i   <   2*n   -1   ;   i++)  
          {  
                if(i   <   n)  
                        haffTree[i].weight   =   weight[i]   ;  
                else  
                        haffTree[i].weight   =   0.0   ;  
                haffTree[i].parent   =   0   ;  
                haffTree[i].flag   =   0   ;  
                haffTree[i].leftchild   =   -1   ;  
                haffTree[i].rightchild   =   -1   ;  
          }  
       
       
      //构造哈夫曼树haffTree[]的n-1个非叶结点      
      for(int   i   =   0   ;   i   <   n-1   ;   i++)  
          {  
                m1   =   m2   =   MaxValue   ;  
                x1   =   x2   =   0   ;  
                for(j=0   ;   j   <   n+i   ;   j++)  
                      {  
                            if(haffTree[j].weight   <   m1   &&   haffTree[j].flag   ==   0)  
                                  {  
                                        m2   =   m1   ;  
                                        x2   =   x1   ;  
                                        m1   =   haffTree[j].weight   ;  
                                        x1   =   j   ;  
                                  }  
                            else      
                                    if(haffTree[j].weight   <   m2   &&   haffTree[j].flag   ==   0)  
                                            {  
                                                  m2   =   haffTree[j].weight   ;  
                                                  x2   =   j   ;  
                                            }  
                        }  
                 
                 
        //将找出的两棵权值最小的子树合并为一棵子树          
                haffTree[x1].parent   =   n+1   ;  
                haffTree[x2].parent   =   n+1   ;  
                haffTree[x1].flag   =   1   ;  
                haffTree[x2].flag   =   1   ;  
                haffTree[n+i].weight   =   haffTree[x1].weight   +   haffTree[x2].weight   ;  
                haffTree[n+i].leftchild   =   x1   ;  
                haffTree[n+i].rightchild   =   x2   ;  
          }  
  }  
   
   
  //由n个结点的哈夫曼树haffTree[]构造哈夫曼编码    
  void   HaffmanCode(HaffNode   haffTree[]   ,   int   n   ,   Code   haffCode[])  
  {  
        Code   *cd   =   new   Code   ;  
        int   child   ,   parent   ;  
         
        //求n个叶结点的哈夫曼编码    
        for(int   i=0   ;   i   <   n   ;   i++)  
            {  
                  cd->start   =   n   -   1   ;  
                  cd->weight   =   haffTree[i].weight   ;  
                  child   =   i   ;  
                  parent   =   haffTree[child].parent   ;  
                   
                  //由叶结点向上直到根结点    
                  while(parent   !=   0)  
                      {  
                            if(haffTree[parent].leftchild   ==   child)  
                                    cd->bit[cd->start]   =   0   ;                           //左孩子结点的编码为0    
                            else  
                                    cd->bit[cd->start]   =   1   ;                           //右孩子结点的编码为1    
                            cd->start   --   ;  
                            child   =   parent   ;  
                            parent   =   haffTree[child].parent   ;  
                        }  
                     
            //保存每个叶结点的编码和不等长编码的起始位              
                    for(int   j   =   cd->start   +   1   ;   j   <   n   ;   j++)          
                        {   haffCode[i].bit[j]   =   cd->bit[j]   ;   }  
                    haffCode[i].start   =   cd->start   ;  
                    haffCode[i].weight   =   cd->weight   ;                       //记住编码对应权值的字符    
            }  
  }    
   
   
  int   main()  
  {  
      int   i   ,   j   ,   n   =   6   ;  
      float   weight[]   =   {0.25   ,   0.25   ,   0.20   ,   0.15   ,   0.10   ,   0.05}   ;  
      HaffNode   *   myHaffTree   =   new   HaffNode[2*n   -   1]   ;  
      Code   *   myHaffCode   =   new   Code[n]   ;  
      if(n   >   MaxN)  
            {  
                cout   <<   "定义的n越界   ,   请修改MaxN."   <<   endl   ;  
                exit(1)   ;  
            }  
        Haffman(weight   ,   n   ,   myHaffTree)   ;  
        HaffmanCode(myHaffTree   ,   n   ,   myHaffCode)   ;  
         
        for(i   =   0   ;   i   <   n   ;   i++)  
            {  
                  cout   <<   "Weight   ="   <<   myHaffCode[i].weight   <<   "     ;         Code   ="   ;  
                  for(j   =   myHaffCode[i].start   +   1   ;   j   <   n   ;   j++)  
                          {   cout   <<   myHaffCode[i].bit[j]   ;   }  
                  cout   <<   endl   ;  
            }  
             
      system("pause")   ;  
       
  }        
                                 
                   
  问题点数:60、回复次数:6Top

1 楼kikikind(可乐)回复于 2006-03-04 15:19:26 得分 0

我发现错误了~~~修正如下:  
  #include<iostream>  
  #include<stdlib.h>  
  using   namespace   std   ;  
   
  const   float   MaxValue   =   2.0     ;                   //初始设定的权值最大值    
  const   int   MaxBit   =   10   ;                               //初始设定的最大编码位数    
  const     int   MaxN   =   20   ;                                 //初始设定的最大结点个数    
   
   
  //哈夫曼数的结点结构    
  struct   HaffNode  
  {  
        float   weight     ;                             //权值    
        int   flag     ;                                     //标记    
        int   parent   ;                                   //双亲结点下标    
        int   leftchild   ;                             //左孩子下标    
        int   rightchild   ;                           //右孩子下标    
  }     ;  
   
   
  //存放哈夫曼编码的数组元素结构    
  struct   Code  
  {  
        int   bit[MaxN]     ;                           //数组    
        int   start     ;                                   //编码的起始下标    
        float   weight   ;                               //字符的权值    
  }     ;  
   
   
  //建立叶结点个数为n权值数组为weight的哈夫曼树haffTree    
  void     Haffman(float   weight[]   ,   int   n   ,   HaffNode   haffTree[])  
  {  
      int   j   ,   x1   ,   x2   ;  
      float   m1   ,   m2     ;  
   
      int   index   =   n;         //新增变量,用来记录父结点位置  
   
       
      //哈夫曼树haffTree[]初始化。n个叶结点共有2n-1个结点    
      for(int   i   =   0   ;   i   <   2*n   -1   ;   i++)  
          {  
                if(i   <   n)  
                        haffTree[i].weight   =   weight[i]   ;  
                else  
                        haffTree[i].weight   =   0.0   ;  
                haffTree[i].parent   =   0   ;  
                haffTree[i].flag   =   0   ;  
                haffTree[i].leftchild   =   -1   ;  
                haffTree[i].rightchild   =   -1   ;  
          }  
       
       
      //构造哈夫曼树haffTree[]的n-1个非叶结点      
      for(i   =   0   ;   i   <   n-1   ;   i++)  
          {  
                m1   =   m2   =   MaxValue   ;  
                x1   =   x2   =   0   ;  
                for(j=0   ;   j   <   n+i   ;   j++)  
                      {  
                            if(haffTree[j].weight   <   m1   &&   haffTree[j].flag   ==   0)  
                                  {  
                                        m2   =   m1   ;  
                                        x2   =   x1   ;  
                                        m1   =   haffTree[j].weight   ; //m1   保存当前最少值结点  
                                        x1   =   j   ; //当前最少值下标  
                                  }  
                            else      
                                    if(haffTree[j].weight   <   m2   &&   haffTree[j].flag   ==   0)  
                                            {  
                                                  m2   =   haffTree[j].weight   ; //m1   保存当前第二最少值结点  
                                                  x2   =   j   ; //当前第二最少值下标  
                                            }  
                        }  
                 
                 
        //将找出的两棵权值最小的子树合并为一棵子树    
         
   
                //haffTree[x1].parent   =   n+1   ; //有问题:  
                //haffTree[x2].parent   =   n+1   ;  
        haffTree[x1].parent   =haffTree[x2].parent   =   index++;  
                haffTree[x1].flag   =   1   ;  
                haffTree[x2].flag   =   1   ;  
                haffTree[n+i].weight   =   haffTree[x1].weight   +   haffTree[x2].weight   ;  
                haffTree[n+i].leftchild   =   x1   ;  
                haffTree[n+i].rightchild   =   x2   ;  
          }  
  }  
   
   
  //由n个结点的哈夫曼树haffTree[]构造哈夫曼编码    
  void   HaffmanCode(HaffNode   haffTree[]   ,   int   n   ,   Code   haffCode[])  
  {  
        Code   *cd   =   new   Code   ;  
        int   child   ,   parent   ;  
         
        //求n个叶结点的哈夫曼编码    
        for(int   i=0   ;   i   <   n   ;   i++)  
            {  
                  cd->start   =   n   -   1   ;  
                  cd->weight   =   haffTree[i].weight   ;  
                  child   =   i   ;  
                  parent   =   haffTree[child].parent   ;  
                   
                  //由叶结点向上直到根结点    
                  while(parent   !=   0)  
                      {  
                            if(haffTree[parent].leftchild   ==   child)  
                                    cd->bit[cd->start]   =   0   ;                           //左孩子结点的编码为0    
                            else  
                                    cd->bit[cd->start]   =   1   ;                           //右孩子结点的编码为1    
                            cd->start   --   ;  
                            child   =   parent   ;  
                            parent   =   haffTree[child].parent   ;  
                        }  
                     
            //保存每个叶结点的编码和不等长编码的起始位              
                    for(int   j   =   cd->start   +   1   ;   j   <   n   ;   j++)          
                    {  
    haffCode[i].bit[j]   =   cd->bit[j]   ;    
    }  
                    haffCode[i].start   =   cd->start   ;  
                    haffCode[i].weight   =   cd->weight   ;                       //记住编码对应权值的字符    
            }  
  }    
   
   
  int   main()  
  {  
      int   i   ,   j   ,   n   =   6   ;  
      float   weight[]   =   {0.25   ,   0.25   ,   0.20   ,   0.15   ,   0.10   ,   0.05}   ;  
      HaffNode   *   myHaffTree   =   new   HaffNode[2*n   -   1]   ;  
      Code   *   myHaffCode   =   new   Code[n]   ;  
      if(n   >   MaxN)  
            {  
                cout   <<   "定义的n越界   ,   请修改MaxN."   <<   endl   ;  
                exit(1)   ;  
            }  
        Haffman(weight   ,   n   ,   myHaffTree)   ;  
        HaffmanCode(myHaffTree   ,   n   ,   myHaffCode)   ;  
         
        for(i   =   0   ;   i   <   n   ;   i++)  
            {  
                  cout   <<   "Weight   ="   <<   myHaffCode[i].weight   <<   "     ;         Code   ="   ;  
                  for(j   =   myHaffCode[i].start   +   1   ;   j   <   n   ;   j++)  
                  {    
  cout   <<   myHaffCode[i].bit[j]   ;    
  }  
                  cout   <<   endl   ;  
            }  
             
      system("pause")   ;  
   
      return   0;  
       
  }      
  ---------------------------------  
  原处这里每次都将父结点指向同一地方了~~~  
  haffTree[x1].parent   =   n+1   ; //有问题:  
  haffTree[x2].parent   =   n+1   ;  
  所以要增加一个变里   index   初始值为   n  
         
  haffTree[x1].parent   =haffTree[x2].parent   =   index++;  
   
  这样每次找出两个最小的值,就增它放在   haffTree[]   数组的第n+1位开始~~~~  
  (因为本身输入的初始结点放在了   0   ~   n-1的位置上~~~~所以n+1的位置就是从haffTree[n]   开始,所以index初始值为   n)  
   
  --------------------------  
  算法不错哦~~~~好好学习哦~!!:)Top

2 楼manplus(魅力加加)回复于 2006-03-04 15:54:32 得分 0

markTop

3 楼yuucyf(天赐)回复于 2006-03-04 16:48:23 得分 0

谢谢!  
  确实是这里错:  
   
  haffTree[x1].parent   =   n+1   ; //有问题:  
  haffTree[x2].parent   =   n+1   ;  
   
  把它改为这样就好了:  
   
  haffTree[x1].parent   =   n+i   ;  
  haffTree[x2].parent   =   n+i   ;  
   
  i和1,害我找不到!!!!  
   
  非常感谢你,是你帮我找到错误!!!  
   
  Top

4 楼kikikind(可乐)回复于 2006-03-05 11:07:37 得分 0

呵呵~~~~帮我加点分哈~~!Top

5 楼yuucyf(天赐)回复于 2006-03-05 12:15:14 得分 0

怎么加分呀!  
  晕!我以为回答了就有分呢!  
  不好意思!我想加,但不知道在那!!!Top

6 楼coziness(coziness)回复于 2006-05-28 20:49:31 得分 0

怎么没结贴呢?  
  点管理后,输入密码就可以给分解贴啊Top

相关问题

  • 关于哈夫曼树~~~~~
  • 哈夫曼树的问题!!
  • 什么是哈夫曼最优树?
  • 哈夫曼树的算法编码
  • 500分求哈夫曼树的算法
  • 哈夫曼树的问题 有死循环 怎么处理
  • 高分急求--关于哈夫曼树生成演示程序
  • 在线征求:哈夫曼树算法的C++代码实现!!
  • 一个关于哈夫曼树的问题,请大家帮帮我这只小菜鸟好吗??
  • 高分在线求:二叉树(哈夫曼树)在地理信息系统(GIS)中应用的案例讲解!! 谢谢

关键词

  • 结点
  • 编码
  • 字符
  • start
  • 结构
  • code
  • hafftree
  • 权值
  • haffnode
  • 下标

得分解答快速导航

  • 帖主:yuucyf

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo