zoukankan      html  css  js  c++  java
  • 求哈夫曼树的编码

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #define N 20
      5 #define M 2*N-1
      6 typedef struct
      7 //哈夫曼树的类型定义
      8 {
      9     int weight;
     10     int parent;
     11     int LChild;
     12     int RChild;
     13 }HTNode,HuffmanTree[M+1];
     14 typedef char *HuffmanCode[N+1];
     15 void CrtHuffmanTree(HuffmanTree ht,int w[],int n)//构造哈夫曼树ht[M+1],w[]存放n个权值
     16 
     17 {
     18     int i,k,Lnode,Rnode,Min1,Min2,max=0;
     19     int m=2*n-1;
     20     for(i=1;i<=n;i++)    //叶子结点初始化
     21     {
     22         ht[i].weight=w[i];
     23         ht[i].parent=0;
     24         ht[i].LChild=0;
     25         ht[i].RChild=0;        
     26     }
     27     /[i]={ w[i],0,0,0};
     28     for(i=n+1;i<=m;i++)    //非叶子结点初始化
     29     /[i]={0,0,0,0};
     30     {
     31         ht[i].weight=0;
     32         ht[i].parent=0;
     33         ht[i].LChild=0;
     34         ht[i].RChild=0;    
     35     }
     36 
     37 
     38 /*
     39 
     40     for(i=1;i<=m;i++)
     41         {
     42             printf(" %d,",w[i]);
     43         }
     44     printf(" %n");
     45     for(i=1;i<=m;i++)
     46         {
     47             printf(" %d,",ht[i].weight);
     48         }
     49     printf(" %d
    ",max);
     50 
     51 */
     52 
     53 
     54 
     55     for(i=n+1;i<=m;i++)//建立哈夫曼树
     56     {    
     57         Min1=Min2=10000;
     58         Lnode=Rnode=0;//Lnode存放最小值的位置,Rnode存放第二最小值的位置
     59         for(k=1;k<i;k++)//只在尚未构造二叉树的结点中查找最小的两个结点
     60         {
     61             if(ht[k].parent==0)
     62             {
     63                 if(ht[k].weight<Min1)//查找当前最小值
     64                 {
     65                     Min2=Min1;
     66                     Rnode=Lnode;
     67                     Min1=ht[k].weight;
     68                     Lnode=k;
     69                 }
     70                 else
     71                     if(k!=Lnode&&ht[k].weight<Min2)//查找当前第二最小值
     72                     {
     73                     Min2=ht[k].weight;
     74                     Rnode=k;
     75                     }                    
     76             }
     77         }
     78         ht[i].weight=Min1+Min2;
     79         ht[i].LChild=Lnode;ht[i].RChild=Rnode;
     80         ht[Lnode].parent=i;ht[Rnode].parent=i;
     81     }
     82 printf("
    哈夫曼树的终态
    序号	Weight	Parent	LChild	RChild
    ");
     83 for(i=1;i<=m;i++)//测试代码
     84 {
     85     printf("%d",i);
     86     printf("    %d",ht[i].weight);
     87     printf("    %d",ht[i].parent);
     88     printf("    %d",ht[i].LChild);
     89     printf("    %d",ht[i].RChild);
     90     printf("
    ");
     91 }
     92 printf("
    ");
     93 
     94     
     95 }
     96 void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n)
     97 //从叶子结点到根,逆求每个叶子结点对应的哈夫曼编码,左0右1
     98 {
     99     char *cd;
    100     int i,j,c,p,start;
    101     cd=(char *)malloc(n*sizeof(char));
    102     cd[n-1]='';
    103     for(i=1;i<=n;i++)
    104     {
    105         start=n-1;
    106         c=i;p=ht[i].parent;    //寻找该叶子结点的父母
    107         while(p!=0)
    108         {
    109             --start;
    110             if(ht[p].LChild==c) 
    111             cd[start]='0';//判断是左边还是右边
    112             else
    113                 cd[start]='1';
    114             c=p;p=ht[p].parent;//继续向上倒推
    115         }
    116         hc[i]=(char *)malloc((n-start)*sizeof(char));
    117         //strcpy(hc[i],&cd[start]);
    118         for(j=0;j<n-1;j++)
    119         {
    120             if(cd[j]=='0'||cd[j]=='1')
    121             printf("%c",cd[j]);
    122         }    
    123         printf("	");
    124         for(j=0;j<n-1;j++)
    125         {
    126             cd[j]=' ';
    127         }    
    128     }
    129     free(cd);
    130 }
    131 void main()
    132 {
    133     HuffmanTree ht1;
    134     HuffmanCode hc;
    135     char ch[20];
    136     int i,a,w[20];
    137     printf("请输入字符个数(小于20):");
    138     scanf("%d",&a);
    139     printf("请输入字符:");
    140     getchar();
    141     for(i=1;i<=a;i++)
    142     {
    143         ch[i]=getchar();
    144     }
    145     getchar();
    146     printf("请输入各个字符对应的权值:");
    147     for(i=1;i<=a;i++)
    148     {
    149         scanf("%d",&w[i]);
    150     }
    151     CrtHuffmanTree(ht1,w,a);
    152     printf("
    		s对各字符的哈夫曼树编码
    ");
    153     printf("	字符	");    
    154     for(i=1;i<=a;i++)
    155     {
    156         printf("%c	",ch[i]);
    157         
    158     }
    159     printf("
    	权值	");
    160     for(i=1;i<=a;i++)
    161         printf("%d	",w[i]);
    162     printf("
      哈夫曼编码	");
    163     CrtHuffmanCode(ht1,hc,a);
    164     printf("
    ");
    165 }

     

  • 相关阅读:
    C# 英语纠错 LanguageTool
    WPF TreeView 虚拟化-设置滚动到选中项
    C# 同步更新系统时间
    C# 重置IE安全等级
    C# IE环境
    C# IE环境
    WPF ObservableCollection 异步调用问题
    C# 以函数Action/Func/Task作为方法参数
    WPF Geometry 引用Path数据
    ResourceDictionary主题资源替换(一) :通过加载顺序来覆盖之前的主题资源
  • 原文地址:https://www.cnblogs.com/eternity-twinkle/p/8971975.html
Copyright © 2011-2022 走看看