哈夫曼树

编写程序实现构造哈夫曼树,并求解哈夫曼编码


#include<bits/stdc++.h>
#include<cstring>
using namespace std;
///哈夫曼树的存储表示
typedef struct{
    char data;
   int weight;
   int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;///动态分配数组存储哈夫曼编码
void Select(HuffmanTree HT, int n, int &s1, int &s2)
  {
      ///前两个for循环找所有结点中权值最小的点
      for (int i = 1; i <= n; i++)
      {
          if (HT[i].parent == 0)
          {
              s1 = i;
              break;
          }
      }
      for (int i = 1; i <= n; i++)
      {
          if (HT[i].weight < HT[s1].weight && HT[i].parent == 0)
              s1 = i;
      }
      ///后两个for循环找到所有结点中权值第二小的点
      for (int i = 1; i <= n; i++)
      {
          if (HT[i].parent == 0 && i != s1)
          {
              s2 = i;
              break;
          }
      }
      for (int i = 1; i <= n; i++)
      {
          if (HT[i].weight < HT[s2].weight && HT[i].parent == 0 && i!= s1)
              s2 = i;
      }
  }
void CreateHuffmanTree(HuffmanTree &HT,int n)
{
    int m,s1,s2;
    if(n<=1) return ;
    m=2*n-1;
    HT=new HTNode[m+1];
    for(int i=1;i<=m;i++)
    {
        HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;
    }///初始化

    for(int i=1;i<=n;i++)
        {
        printf("请输入第%d个叶子结点的权值:\n",i);
        getchar();
        scanf("%c %d",&HT[i].data,&HT[i].weight);
        }
    for(int i=n+1;i<=m;i++)
    {
        ///通过n-1次的选择、删除、合并来构造哈夫曼树
        Select(HT,i-1,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("哈夫曼树创建完成\n");
}
///从叶子到根逆向求每个字符的哈夫曼编码,储存在编码表HC中
void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{
    int start,c,f;
    HC=new char*[n+1];///分配储存n个字符编码的编码表空间
    char *cd=new char[n];///分配临时存储字符编码的动态空间
    cd[n-1]='\0';
    int i;
    for(i=1;i<=n;++i)
    {

        start=n-1;
        c=i;
        f=HT[i].parent;
        while(f!=0)///从叶子结点开始回溯,直到根结点
        {
            --start;
            if(HT[f].lchild==c) cd[start]='0';
            else cd[start]='1';
            c=f;
            f=HT[f].parent;
        }
        HC[i]=new char[n-start];///为第i个字符编码分配空间
        strcpy(HC[i],&cd[start]);///把求得编码的首地址从cd[start]复制到HC的当前行中
    }
    delete cd;
}

int main()
{
    int s1,s2;
    int n;
    HuffmanTree T;
    HuffmanCode hc;
    printf("叶子节点数:\n");
    scanf("%d",&n);
    CreateHuffmanTree(T,n);
    CreateHuffmanCode(T,hc,n);
    for(int i=1;i<=n;i++)
    {
        cout<<T[i].data<<" "<<hc[i]<<endl;
    }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值