Huffman树的创建及编码

算法-基础数据结构 专栏收录该内容
14 篇文章 0 订阅
直接上代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define  inf 99999999
struct HuffmanNode{
  int weight;
  int lchild,rchild,parent;
};
void Select(struct HuffmanNode *p,int n,int& num1,int& num2){
   int i;
   int min1,min2;
   min1=inf;
   for(i=1;i<=n;i++){      //在还没有被选择的节点中,选择最小的节点
    if(p[i].parent==0&&p[i].weight<min1){
      min1=p[i].weight;
    }
   }
   for(i=1;i<=n;i++){
    if(p[i].parent==0&&p[i].weight==min1){//找到该节点的序号
     num1=i;
     p[i].parent=1;//将其父母置为非空,表明这个节点已经被选
     break;
    }
   }
   min2=inf;
    for(i=1;i<=n;i++){      //在还没有被选择的节点中,选择次小的节点
     if(p[i].parent==0&&p[i].weight<min2){
      min2=p[i].weight;
   }
}
     for(i=1;i<=n;i++){
    if(p[i].parent==0&&p[i].weight==min2){  //找到该节点的序号
     num2=i;
      p[i].parent=1;//将其父母置为非空,表明这个节点已经被选
     break;
    }
   }
}
void Huffman_Coding(int n,struct HuffmanNode* &head,char** &HC){
  int m,i,s1,s2;//构造赫夫曼树
  if(n<1)
  printf("无法构造赫夫曼树\n");
  m=2*n-1;
  head=(struct HuffmanNode *)malloc((m+1)*sizeof(struct HuffmanNode));//0号元素不用
  for(i=1;i<=m;i++){
   if(i<=n)
   scanf("%d",&head[i].weight);
   else
   head[i].weight=0;
   head[i].lchild=0;
   head[i].rchild=0;
   head[i].parent=0;
  }
  for(i=n+1;i<=m;i++){
   Select(head,i-1,s1,s2);
   head[s1].parent=i;
   head[s2].parent=i;
   head[i].lchild=s1;
   head[i].rchild=s2;
   head[i].weight=head[s1].weight+head[s2].weight;
  }
  char *cd;
  int start,c,f;   //对赫夫曼树进行编码
  HC=(char **)malloc((n+1)*sizeof(char *));
  cd=(char *)malloc(n*sizeof(char));
  cd[n-1]='\0';
  for(i=1;i<=n;i++){
   start=n-1;
   for(c=i,f=head[i].parent;f!=0;c=f,f=head[f].parent){
     if(head[f].lchild==c)
     cd[--start]='0';
     else
     cd[--start]='1';
   }
   HC[i]=(char *)malloc((n-start)*sizeof(char));
   strcpy(HC[i],&cd[start]);
  }
  free(cd);
}
int main()
{
    int n,i;
    struct HuffmanNode *head;
    char **HC;
    printf("请输入赫夫曼树的节点个数\n");
    scanf("%d",&n);
    Huffman_Coding(n,head,HC);
    printf("输出赫夫曼树的编码\n");
    for(i=1;i<=n;i++){
    printf("%s\n",HC[i]);
    }
    return 0;
}

  • 1
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值