问题:无法调用编写的哈夫曼编码函数,输出为空白
以下为编码函数
void Encoding(HuffNode*&ht,HuffCode&HC,int n){
HC = (HuffCode)malloc(sizeof(char*)*n); //共n个叶子结点对应n个编码
printf("1111");
char*code = (char*)malloc(sizeof(char)*(n-1+1)); //每个编码最多只有n-1位,但要多存一个'\0'所以在加个1
code[n-1] = '\0';
int i,start,current,father;
for(i=1;i<=n;i++){ //遍历n个叶子结点
start = n-1; //code数组start指针置于n-1处
current = i;
father = ht[i].parent;
while(father!=0){ //每个结点遍历到根结点为止
if(ht[father].lchild==current){ //当前结点是其父亲的左孩子
code[--start] = '0';
}
else{
code[--start] = '1'; //当前结点是其父亲的右孩子
}
printf("code[start] = %c\n",code[start]);
current = father; //继续下一个结点的遍历
father = ht[father].parent;
//printf("start = %d",start);
}
HC[i] = (char*)malloc(sizeof(char)*(n-start)); //HC[i]存放的是第i位字符的编码,长度为n-start
strcpy(HC[i],code);
}
free(code);
}
问题:
完整代码:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef struct {
double weight; //权值
int parent;
int lchild;
int rchild;
}HuffNode; //构建哈夫曼树的三叉静态链表
typedef char** HuffCode; //构建HC数组存放的是每个字符对应的编码
void Select(HuffNode*&ht,int range,int &s1,int &s2){ // 在1-range范围内寻找最小和次小的结点
int min ;
int i;
for(i=1;i<=range;i++){
if(ht[i].parent==0){
min = i;
break;
} //找到第一个叶子结点
}
for(;i<=range;i++){ //继续找
if(ht[i].parent==0&&ht[i].weight<ht[min].weight){
min = i;
}
}
s1 = min; //找到range范围内最小的结点
for(i=1;i<=range;i++){
if(ht[i].parent==0&&i!=s1){
min = i;
break;
}
}
for(;i<=range;i++){
if(ht[i].parent==0&&i!=s1&&ht[i].weight<ht[min].weight){
min = i;
}
}
s2 = min ;//找到range范围内次小的结点
}
void CreatHaffTree(HuffNode*&ht,double*w,int n){ //构建哈夫曼树
int m = 2*n-1; //总结点数
ht = (HuffNode*)malloc(sizeof(HuffNode)*m+1); //开辟三叉链表的空间,为便于理解开辟m+1的空间,空出第0个空间
int i;
int s1,s2;
char ch; //用于n个叶子结点的data域
for(i=1;i<=n;i++){
ht[i].weight = w[i-1];
ht[i].parent = 0;
ht[i].lchild = ht[i].rchild = 0;
}
for(i=n+1;i<=m;i++){
ht[i].weight = 0;
ht[i].parent = 0;
ht[i].lchild = ht[i].rchild = 0;
}
//初始化静态链表
for(i=n+1;i<=m;i++){
Select(ht,i-1,s1,s2); //找到每次i-1范围内最小和次小的根结点
ht[i].weight = ht[s1].weight+ht[s2].weight;
ht[i].lchild = s1;
ht[i].rchild = s2;
ht[s1].parent = ht[s2].parent = i;
}
}
void PrintHuffTree(HuffNode*ht,int n){
int i;
printf("i\tweight\tparent\tlchild\trchild"); //调整输出表头
printf("\n");
for(i=1;i<=2*n-1;i++){
printf("%d\t%-0.3f\t%6d\t%d\t%d",i,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
printf("\n");
}
}
void Encoding(HuffNode*&ht,HuffCode&HC,int n){
HC = (HuffCode)malloc(sizeof(char*)*n); //共n个叶子结点对应n个编码
printf("1111");
char*code = (char*)malloc(sizeof(char)*(n-1+1)); //每个编码最多只有n-1位,但要多存一个'\0'所以在加个1
code[n-1] = '\0';
int i,start,current,father;
for(i=1;i<=n;i++){ //遍历n个叶子结点
start = n-1; //code数组start指针置于n-1处
current = i;
father = ht[i].parent;
while(father!=0){ //每个结点遍历到根结点为止
if(ht[father].lchild==current){ //当前结点是其父亲的左孩子
code[--start] = '0';
}
else{
code[--start] = '1'; //当前结点是其父亲的右孩子
}
printf("code[start] = %c\n",code[start]);
current = father; //继续下一个结点的遍历
father = ht[father].parent;
//printf("start = %d",start);
}
HC[i] = (char*)malloc(sizeof(char)*(n-start)); //HC[i]存放的是第i位字符的编码,长度为n-start
strcpy(HC[i],code);
}
free(code);
}
void DisplayCode(HuffNode*ht,HuffCode&HC,int n){
printf("1111");
int i;
char ch = 'A';
for(i=1;i<=n;i++){
printf("%c:%s",ch++,HC[i]);
printf("\n");
}
}
int main(){
double num;
int n;
double *w; //用于存放所有叶子结点对应的权值数组
HuffNode*ht;
HuffCode HC; //HC数组存放叶子结点的所有编码
printf("请输入要创建的哈夫曼树的初始叶子结点数:\n");
scanf("%d",&n);
w = (double*)malloc(sizeof(double)*n);
printf("请输入每个叶子结点所带的权值\n");
for(int i=0;i<n;i++){
scanf("%lf",&num);
w[i] = num;
}
CreatHaffTree(ht,w,n);
PrintHuffTree(ht,n);
Encoding(ht,HC,n);
DisplayCode(ht,HC,n);
return 0;
}