| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 842 人关注过本帖
标题:s 求助,关于哈夫曼树编码,出现的问题该怎么修改..
只看楼主 加入收藏
九亿少女的梦
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2017-4-9
结帖率:66.67%
收藏
已结贴  问题点数:5 回复次数:3 
s 求助,关于哈夫曼树编码,出现的问题该怎么修改..
程序代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
typedef struct
{
int weight;//权值分量(可放大取整)
int parent,lchild,rchild; //双亲和孩子分量
}HTNode,*HuffmanTree;//用动态数组存储Huffman树

typedef  char**HuffmanCode; //动态数组存储Huffman编码表


void Select(HuffmanTree HT,int n,int &s1,int &s2) 
{
    int i,j;

 
    for(i=1;i<=n;i++) 
        if(!HT[i].parent)
        {
            s1=i;
            break;
        }
        for(j=i+1;j<=n;j++)
            if(!HT[j].parent)
            {
                s2 = j;
                break;
            }
            for(i=1;i<=n;i++)
                if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i))
                    s1=i;
                
        for(j = 1;j <= n;j++)
            if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j))
                s2=j;
}


void  HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)
{
    char *cd;
    if  (n<=1) 
        return;
    HuffmanTree p;

    int m,i,j,s1,s2,start,c,f;
    m=2*n-1;    //n0个叶子的HuffmanTree共有2n0-1个结点;
    HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); //0单元未用
    
    for(i=1; i<=n; ++i,++w)//给前n0个单元初始化为权值
    {
        HT[i].weight=w[i-1];
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0; 
    }
    for(i=n+1;i<=m;++i,++p)     //对叶子之后的存储单元清零
    {
        HT[i].weight=0;
        HT[i].lchild=0;
        HT[i].parent=0;
        HT[i].rchild=0;
    }

    
    for(i=n+1;i<=m; ++i)
    {    //建Huffman树(从叶子后开始存内结点) 
        Select(HT, i-1, s1, s2);   //在HT[1…i-1]选择parent为0且weight最小的两个结点,其序号分别为S1和和s2
        HT[s1].parent=i; HT[s2].parent=i; 
        HT[i].lchild=s1; HT[i].rchild=s2;  
        HT[i].weight=HT[s1].weight+HT[s2].weight;
        printf("nselect: s1=%d   s2=%d\n", s1, s2);   
        printf("  结点  weight  parent  lchild  rchild");  
        for (j=1;j<=i;j++)   
            printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,HT[j].parent,HT[j].lchild, HT[j].rchild);
   
        printf("    按任意键,继续 ...");
   
        getchar();

    }

    HC=(HuffmanCode)malloc((n+1)*sizeof(char*));              //分配n个字符编码的头指针向量(一维数组)
    cd=(char*) malloc(n*sizeof(char)); //分配求编码的工作空间(n) 
    cd[n-1]='\0';  //编码结束符(从cd[0]~cd[n-1]为合法空间)

    for(i=1;i<=n;++i) //逐个字符求Huffman编码
    {   
        start=n-1;   //编码结束符位置
    
        for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)// c表示正在操作的HT的行下标 //从叶子到根逆向求编码      
            if(HT[f].lchild==c)    
                cd[--start]='0'; //左边取0        
            else                              
                cd[--start]='1'; //右边取1
            HC[i]=(char*)malloc((n-start)*sizeof(char)); //为第i个字符编码分配空间
            strcpy(HC[i],&cd[start]); //从cd复制编码串到HC

    }

    free(cd);  //释放工作空间    
    } //HuffmanCoding




int main() 
{
   HuffmanTree HT;
   HuffmanCode *HC;
   int *w,n,i;
   puts("输入结点数:");
   scanf("%d",&n);
   getchar();
     
   HC = (HuffmanCode *)malloc(n*sizeof(HuffmanCode));
   w = (int *)malloc(n*sizeof(int));
   
   
   for(i=0;i<n;i++)
   {
       printf("输入%d个结点的权值:",i+1);
       scanf("%d",&w[i]);
   }

   HuffmanCoding(HT,*HC,w,n);
   puts("\n各结点的哈夫曼编码:");
   
   for(i=1;i<=n;i++)
       printf("%2d(%4d):%s\n",i,w[i-1],HC[i]);
   getchar();
  }
2017-04-13 17:04
九亿少女的梦
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2017-4-9
收藏
得分:0 
2017-04-15 09:20
marlow
Rank: 6Rank: 6
等 级:侠之大者
威 望:2
帖 子:125
专家分:419
注 册:2016-7-18
收藏
得分:0 
回复 楼主 九亿少女的梦
给你调试了一下,能出结果。但对哈夫曼没有研究,因此代码仍存在问题:
程序代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
typedef struct
{
int weight;//权值分量(可放大取整)
int parent,lchild,rchild; //双亲和孩子分量
}HTNode, *HuffmanTree;//用动态数组存储Huffman树

typedef  char** HuffmanCode; //动态数组存储Huffman编码表


void Select(HuffmanTree HT, int n, int *s1, int *s2) 
{
    int i, j;

 
    for(i=1; i<=n; i++) 
        if(!HT[i].parent)
        {
            *s1=i;
            break;
        }
        for(j=i+1;j<=n;j++)
            if(!HT[j].parent)
            {
                *s2 = j;
                break;
            }
            for(i=1;i<=n;i++)
                if((HT[*s1].weight>HT[i].weight)&&(!HT[i].parent)&&(*s2!=i))
                    *s1=i;
                
        for(j = 1;j <= n;j++)
            if((HT[*s2].weight>HT[j].weight)&&(!HT[j].parent)&&(*s1!=j))
                *s2=j;
}


void  HuffmanCoding(HuffmanTree HT, HuffmanCode HC, int *w, int n)
{
    char *cd;   
     if(n<=1) 
        return;
    HuffmanTree p;

    int m,i,j,s1,s2,start,c,f;
    m=2*n-1;    //n个叶子的HuffmanTree共有2n-1个结点;
    HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); //0单元未用
    
    for(i=1; i<=n; ++i)//给前n个单元初始化为权值
    {
        HT[i].weight=w[i-1];
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0; 
    }
    for(i=n+1;i<=m;++i,++p)     //对叶子之后的存储单元清零
    {
        HT[i].weight=0;
        HT[i].lchild=0;
        HT[i].parent=0;
        HT[i].rchild=0;
    }

    
    for(i=n+1;i<=m; ++i)
    {    //建Huffman树(从叶子后开始存内结点) 
        Select(HT, i-1, &s1, &s2);   //在HT[1…i-1]选择parent为0且weight最小的两个结点,其序号分别为S1和和s2
        HT[s1].parent=i; HT[s2].parent=i; 
        HT[i].lchild=s1; HT[i].rchild=s2;  
        HT[i].weight=HT[s1].weight+HT[s2].weight;
        printf("nselect: s1=%d   s2=%d\n", s1, s2);   
        printf("  结点  weight  parent  lchild  rchild");  
        for (j=1; j<=i; j++)   
            printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,HT[j].parent,HT[j].lchild, HT[j].rchild);
   
        printf("    按任意键,继续 ...");
   
        getchar();

    }

    HC=(HuffmanCode)malloc((n+1)*sizeof(char*));              //分配n个字符编码的头指针向量(一维数组)
    cd=(char*) malloc(n*sizeof(char)); //分配求编码的工作空间(n) 
    cd[n-1]='\0';  //编码结束符(从cd[0]~cd[n-1]为合法空间)

    for(i=1;i<=n;++i) //逐个字符求Huffman编码
    {   
        start=n-1;   //编码结束符位置
    
        for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)// c表示正在操作的HT的行下标 //从叶子到根逆向求编码      
            if(HT[f].lchild==c)    
                cd[--start]='0'; //左边取0        
            else                              
                cd[--start]='1'; //右边取1
            HC[i]=(char*)malloc((n-start)*sizeof(char)); //为第i个字符编码分配空间
            strcpy(HC[i],&cd[start]); //从cd复制编码串到HC

    }

    free(cd);  //释放工作空间    
    } //HuffmanCoding




int main() 
{
   HuffmanTree HT;
   HuffmanCode *HC;
   int *w,n,i;
   puts("输入结点数:");
   scanf("%d",&n);
   getchar();
     
   HC = (HuffmanCode *)malloc(n*sizeof(HuffmanCode));
   w = (int *)malloc(n*sizeof(int));
   
   
   for(i=0;i<n;i++)
   {
       printf("输入%d个结点的权值:",i+1);
       scanf("%d",&w[i]);
   }

   HuffmanCoding(HT,*HC,w,n);
   puts("\n各结点的哈夫曼编码:");
   
   for(i=1;i<=n;i++)
       printf("%2d(%4d):%s\n",i,w[i-1],HC[i]);
   getchar();
  }


[此贴子已经被作者于2017-4-15 23:20编辑过]


一切都在学习、尝试、摸索中
2017-04-15 14:37
marlow
Rank: 6Rank: 6
等 级:侠之大者
威 望:2
帖 子:125
专家分:419
注 册:2016-7-18
收藏
得分:5 
回复 3楼 marlow
研究了一下哈夫曼编码,问题解决了。你的代码主要是语法上的问题,不是算法的问题:
程序代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
typedef struct
{
int weight;//权值分量(可放大取整)
int parent,lchild,rchild; //双亲和孩子分量
}HTNode, *HuffmanTree;//用动态数组存储Huffman树

typedef  char** HuffmanCode; //动态数组存储Huffman编码表


void Select(HuffmanTree HT, int n, int *s1, int *s2) 
{//ht[1...k]中选择parent为0,并且weight最小的两个结点,其序号由其指针变量s1,s2指示 
    int i, j;

 
    for(i=1; i<=n; i++) 
        if(!HT[i].parent){
            *s1=i;
            break;
        }
    for(j=i+1;j<=n;j++)
        if(!HT[j].parent){
                *s2 = j;
                break;
     }
     for(i=1;i<=n;i++)
         if((HT[*s1].weight>HT[i].weight)&&(!HT[i].parent)&&(*s2!=i))
              *s1=i;
                
      for(j = 1;j <= n;j++)
          if((HT[*s2].weight>HT[j].weight)&&(!HT[j].parent)&&(*s1!=j))
               *s2=j;
}


void  HuffmanCoding(HuffmanTree HT, HuffmanCode *HC, int *w, int n)
{
    char *cd;   
     if(n<=1) 
        return;
    HuffmanTree p;

    int m,i,j,s1,s2,start,c,f;
    m=2*n-1;    //n个叶子的HuffmanTree共有2n-1个结点;
    HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); //0单元未用
    
    for(i=1; i<=n; ++i)//给前n个单元初始化为权值
    {
        HT[i].weight=w[i-1]; 
//        printf("第%d个节点的权重%d <- %d\n", i, HT[i].weight,w[i-1]);
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0; 
    }
    
    for(i=n+1;i<=m;++i,++p)     //对叶子之后的存储单元清零
    {
        HT[i].weight=0;
        HT[i].lchild=0;
        HT[i].parent=0;
        HT[i].rchild=0;
    }

    
    for(i=n+1;i<=m; ++i)
    {    //建Huffman树(从叶子后开始存内结点) 
        Select(HT, i-1, &s1, &s2);   //在HT[1…i-1]选择parent为0且weight最小的两个结点,其序号分别为S1和和s2
        HT[s1].parent=i;
        HT[s2].parent=i; 
        HT[i].lchild=s1; 
        HT[i].rchild=s2;  
        HT[i].weight=HT[s1].weight+HT[s2].weight;
//        printf("\nselect: s1=%d   s2=%d\n", s1, s2);   
//        printf("  结点  weight  parent  lchild  rchild");  
//        for (j=1; j<=i; j++)   
//            printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,HT[j].parent,HT[j].lchild, HT[j].rchild);
//        printf("    按任意键,继续 ...");
//        getchar();

    }

//    HC=(HuffmanCode)malloc((n+1)*sizeof(char*));              //分配n个字符编码的头指针向量(一维数组)
    cd=(char*) malloc(n*sizeof(char)); //分配求编码的工作空间(n) 
    cd[n-1]='\0';  //编码结束符(从cd[0]~cd[n-1]为合法空间)

    for(i=1;i<=n;++i) //逐个字符求Huffman编码
    {   
        start=n-1;   //编码结束符位置
    
        for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)// c表示正在操作的HT的行下标 //从叶子到根逆向求编码      
            if(HT[f].lchild==c)    
                cd[--start]='0'; //左边取0        
            else                              
                cd[--start]='1'; //右边取1
            (*HC)[i]=(char*)malloc((n-start)*sizeof(char)); //为第i个字符编码分配空间
            strcpy((*HC)[i],&cd[start]); //从cd复制编码串到HC
     }

    free(cd);  //释放工作空间    
} //HuffmanCoding




int main() 
{
   HuffmanTree HT;
   HuffmanCode HC;
   int *w,n,i;
   puts("输入结点数:");
   scanf("%d",&n);
   getchar();
     
   HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
   w = (int *)malloc(n*sizeof(int));
   
   
   for(i=0;i<n;i++)
   {
       printf("输入%d个结点的权值:",i+1);
       scanf("%d",&w[i]);
   }

   HuffmanCoding(HT,&HC,w,n);
   puts("\n各结点的哈夫曼编码:");
   
   for(i=1;i<=n;i++)
       printf("%2d(%4d):%s\n",i,w[i-1],HC[i]);
   getchar();
  }


[此贴子已经被作者于2017-4-16 00:02编辑过]


一切都在学习、尝试、摸索中
2017-04-15 23:59
快速回复:s 求助,关于哈夫曼树编码,出现的问题该怎么修改..
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.033462 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved