求大大指教,,,写了个C语言数据结构的哈夫曼编码,可是哪里出错了,,,???

/* 哈夫曼编码 */
#include<stdio.h>
#include<stdlib.h> 
#include<string.h>
#include<ctype.h>
#define MAX    100
/*哈夫曼树结点结构定义 */
typedef struct {
 int weight;  //存放字符ch的权值 
 char ch;     //记录字符 
 int lchild, rchild, parent;//存储左孩子、右孩子以及父结点 
} TNode, *PHT;

/* 哈夫曼编码表的元素结构定义  */
typedef struct {
   char ch;       // 编码对应的字符
   char *pcode;   // 指向编码字符串的指针
} TCode, *PCode;
/* 
 *统计字符串text中字符出现的频率,参数n为字符串长度
 *返回值:text中出现的不同种类的字符个数
 *副作用:通过指针参数间接返回两个数组:
 *  1)dict:字符数组,存放 text中出现的不同种类的字符
 *  2)freq:整型数组,存放 text中出现的不同种类的字符的出现频率 
 */
int calc_freq(char text[], int **freq, char **dict, int n){
 int i,j, k, nchar = 0;
 int *pwght;
 char *pch;
 int tokens[256] = {0};
 //根据输入的文本字符串逐一统计字符出现的频率 
 for(i = 0; i < n; ++i){
  tokens[text[i]]++;
 }
 
 //统计共有多少个相异的字符出现在文本串中 
 for(i = 0; i < 256; i++){
  if( tokens[i] > 0 ){
   nchar++;
  }
 }
 //为权重数组分配空间 
 pwght=(int*)malloc(sizeof(int)*nchar);
 if(!pwght){
  printf("为权重数组分配空间失败!\n");
  exit(0);
 }
 
 //为字符数组(字典)分配空间 
 pch=(char *)malloc(sizeof(char)*nchar);
 if( !pch ){
  printf("为字符数组(字典)分配空间失败!\n");
  exit(0);
 }
 
 k = 0;
 for(i = 0; i < 256; ++i){
  if( tokens[i] > 0 ){
   pwght[k] = tokens[i];
   pch[k] = (char)i;  //强制类型转换 
   k++;
  }
 }
 
 *freq = pwght;
 *dict = pch;
 for(i=0;i<nchar;i++)
    printf("%c\t%d\n",pch[i],pwght[i]);
 
 return nchar;
}
/*构建哈夫曼树 */
PHT create_htree( int **freq, int n ){
 PHT pht; 
 int i, lc, rc, ntotal = 0;
 ntotal = (2 * n) - 1; // Huffman树的结点总数
 
 pht = (PHT) malloc( sizeof( TNode ) * ntotal );
 for( i = 0; i < ntotal; ++i ){ // Huffman树结点初始化
  pht[i].weight = (i < n) ? *freq[i] : 0;
  pht[i].lchild = -1; 
  pht[i].rchild = -1; 
  pht[i].parent = -1;
 }
 for( i = n; i < ntotal; ++i ){ // 构建Huffman树
  select_subtree( pht, (i-1), &lc, &rc );
  pht[lc].parent = i; 
  pht[rc].parent = i;
  pht[i].lchild = lc; 
  pht[i].rchild = rc;
  pht[i].weight = pht[lc].weight + pht[rc].weight;
 }
 printf("创建哈夫曼树成功!\n");
 return pht;
}
/*子树选择算法 */
int select_subtree(PHT pht, int n, int *pa, int *pb){//n为哈夫曼树结点数目 
 int id, ida = -1, idb= -1;              // ida存放权重最小的结点下标
 int wa = INT_MAX, wb = INT_MAX;         // wa最小值 wb次小值
 for(id = 0; id <= n; id++){
  if(pht[id].parent == -1){
   if( pht[id].weight < wa ){
    idb = ida;                  // 重置次小值结点下标 
    wb = wa;                    //将较大的权值复制给wb 
    ida = id;                   //重置最小值结点下标 
    wa = pht[id].weight;        //将最小的权值记录为wa 
    }
   else if(pht[id].weight < wb ){  //新权值大于wa小于wb 
       idb = id;                   //重置次小值结点下标 
    wb = pht[id].weight;        //重置次小值 
    }
  }
 }
 *pa = ida; 
 *pb = idb; 
 return 0;
}
/* 根据哈夫曼树pht求哈夫曼编码表book */
void htree_encoding (PHT pht, TCode *book, int n){
 int i, c, p, start; // start表示编码在cd中的起始位置
 char cd[n+1]; 
 cd[n]='\0'; // 临时存放编码
 for(i = 0; i < n; i++){ // 依次求叶子pht[i]的编码
  book[i].ch = pht[i].ch; // 读入叶结点pht[i]对应的字符
  start = n; 
  c = i; // 从叶结点pht[i]开始上溯
  while( p = pht[c].parent > 0){
   if(pht[p].lchild == c) 
      cd[--start]='0'; 
   else 
      cd[--start] ='1'; 
   c = p; 
  } // 继续上溯直到根节点
  strcpy(book[i].pcode, &cd[start]); // 复制编码位串
    }  
    printf("哈夫曼编码成功!\n");
}
void print_htreecode(TCode *book,int n){
 int i;
 for(i=0;i<n;i++){
  printf("%c\t%d\n",book[i].ch,book[i].pcode);
 }
 printf("哈夫曼编码打印成功!\n");
}
 
void main(){
    char text[MAX];
    int scount=0,nchar=0,n;
    int weights[MAX];
    int **freq;
    char **dict;
    PHT pht;
    TCode *book;
    
    //从键盘输入英文字符串 
    printf("请输入英文字符串:\n");
    while((text[scount]=getchar())!='\n')
        scount++; 
        
    //统计字符串中不同字符出现的频率并打印相应信息    
    calc_freq(text,freq,dict,scount);
    
    // 构建哈夫曼树
    create_htree(freq,nchar); 
    
 //遍历哈夫曼树生成哈夫曼编码
 htree_encoding (pht,book,nchar);
 
 printf("打印每个字符的哈夫曼编码如下:\n");
 printf("字符\t编码\n");
 print_htreecode(book,nchar);
 
  
}

lukuang
浏览 1729回答 1
1回答

不偏不易

好怀念,当年我也是能自己写出这些各种树,各种遍历的人啊。现在已经废了。。如何查错。DEBUG,设置断点并一步步走。能正常启动并运行的,只是输出有问题,或者运行过程中出错的,可以选择在每一次输出的语句设置断点。然后每一步输出后,观察变量值是否正确。如果不能启动,直接爆炸的,请先不要在主函数中调用所有的函数,可以先把大部分注释掉,然后一个个测试。其实这一部分应该在编写过程中做,写完一部分就测试一部分。这些都能做到,以后大部分问题,都可以自己解决。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

数据结构