求哈弗曼树的编码

  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\n",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("\n哈夫曼树的终态\n序号\tWeight\tParent\tLChild\tRChild\n");
 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("\n");
 91 }
 92 printf("\n");
 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]=‘\0‘;
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("\t");
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("\n\t\ts对各字符的哈夫曼树编码\n");
153     printf("\t字符\t");
154     for(i=1;i<=a;i++)
155     {
156         printf("%c\t",ch[i]);
157
158     }
159     printf("\n\t权值\t");
160     for(i=1;i<=a;i++)
161         printf("%d\t",w[i]);
162     printf("\n  哈夫曼编码\t");
163     CrtHuffmanCode(ht1,hc,a);
164     printf("\n");
165 }

原文地址:https://www.cnblogs.com/twinkle-/p/8971987.html

时间: 2024-10-19 13:53:29

求哈弗曼树的编码的相关文章

哈弗曼树的构建,哈夫曼编码、译码

哈夫曼树的基本概念 哈夫曼树(Huffman Tree),又叫最优二叉树,指的是对于一组具有确定权值的叶子结点的具有最小带权路径长度的二叉树. (1)路劲(Path):从树中的一个结点到另一个结点之间的分支构成两个结点间的路径. (2)路径长度(Path Length):路径上的分支树. (3)树的路径长度(Path Length of Tree):从树的根结点到每个结点的路径长度之和.在结点数目相同的二叉树中,完全二叉树的路径长度最短. (4)结点的权(Weight of  Node):在一些

数据结构&amp;&amp;哈弗曼树和哈弗曼编码

1.什么是哈夫曼树和哈弗曼编码 大家来看这样一道面试题(题目来自于<程序员面试宝典>).用二进制来编码字符串"abcdabaa",需要能够根据编码,解码回原来的字符串,最少需要多长的二进制字符串? A.12 B.14 C.18 D.24 解析:典型的哈弗曼编码问题:字符串"abcdabaa"有4个a.2个b.1个c.1个d.构造哈弗曼树如下图所示(图好丑).a编码0(1位),b编码10(2位),d编码111(3位).二进制字符串的总长度为1*4+2*2+

哈弗曼树及其操作

1.哈弗曼树的节点声明 1 package com.neusoft.Tree; 2 3 public class HuffmanNode { 4 public int weight; 5 //加入哈夫曼树的标志,flag=0表示该节点没有加入哈夫曼树,=1表示加入 6 public int flag; 7 public HuffmanNode parent,lchild,rchild; 8 public HuffmanNode() { 9 this(0); 10 } 11 public Huff

哈夫曼树及编码

介绍哈夫曼编码之前先介绍一下哈弗曼树: 哈夫曼树:哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度 为叶结点的层数).树的带权路径长度记为WPL= (W1*L1+W2*L2+W3*L3+...+Wn*Ln) ,N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n).可以证明哈夫曼树的WPL是最小的. 哈夫曼树的构

哈弗曼树的建立

哈弗曼树也称为最优二叉树,它是带权路径长度最短的树,权值越大的结点就离根节点越近.(一般在哈弗曼编码中,权值表示出现的概率,即出现的概率越大,那么访问时的路径就越短). 构建哈弗曼树: 将n个权值构造出n棵只有根节点的树,构成森林. 在森林中选出两个根结点的权值最小的树分别做左右孩子合并一棵新树,且新树的根结点权值为左右结点之和. 从森林中删除选取的两棵树,并将构成的新想树插入到森林中. 构建哈弗曼树的步骤图解如下. 代码实现: //哈弗曼树 #include <stdio.h> #inclu

【数据结构】哈夫曼树实现编码译码

根据一段字符串中字符的个数 作为该字符的权值生成哈夫曼树. 然后根据生成的哈夫曼编码,对任意字符串实现编码,对任意二进制串实现译码. 程序运行结果: 1.程序主界面: 2.根据字符串 创建哈夫曼树及编码: 3.生成的编码表如下: 4.根据生成的哈夫曼编码对字符串编码: 5.生成的编码保存在文件中: 6.对二进制串译码: 结果: 代码: 哈夫曼树的生成和编码的常见,以及编码和译码函数 //_HuffmanTree_H #ifndef _HuffmanTree_H #define _HuffmanT

java实现哈弗曼树

O(∩_∩)O~~ 概述 我想学过数据结构的小伙伴一定都认识哈弗曼,这位大神发明了大名鼎鼎的“最优二叉树”,为了纪念他呢,我们称之为“哈弗曼树”.哈弗曼树可以用于哈弗曼编码,编码的话学问可就大了,比如用于压缩,用于密码学等.今天一起来看看哈弗曼树到底是什么东东. 概念 当然,套路之一,首先我们要了解一些基本概念. 1.              路径长度:从树中的一个结点到另一个结点之间的分支构成这两个结点的路径,路径上的分支数目称为路径长度. 2.              树的路径长度:从树

哈夫曼树与编码译码实现

一.哈弗曼树的基本概念. 哈夫曼树,又称最优树,是一类带权路径长度最短的树.下面有几个概念: (1)路径. 树中一个结点到另一个结点之间的分支构成这两个结点之间的路径. (2)路径长度. 路径上的分枝数目. (3)树的路径长度. 从树根到每一个结点的路径长度之和. (4)结点的带权路径长度. 从该结点到树根之间的路径长度与结点上权的乘积. (5)树的带权路径长度. 树中所有叶子节点的带权路径长度之和.通常记作: 带权路径长度WPL最小的二叉树叫做最优二叉树或哈夫曼树. 二.构造哈夫曼树. 采用哈

简单哈弗曼树(Java)

哈夫曼树的实现 1.编码思想 哈夫曼编码是一种变长的编码方案,字符的编码根据使用频率的的不同而长短不一, 使用频率高的字符其编码较短,使用频率低的字符编码较长,从而使所有的编码总长度为最短. 统计原始数据中个新号符号的频率,安频率高低的次序排列 将两个频率最小的相加,作为原本两个节点的父节点,次父节点的频率为子节点之和 重复上述两部,直到和为只剩下一个元素,那么这个元素就是根 2.解码思想 利用Haffman树进行解码,已知一个二进制位串S,从串S的第一位出发,逐位的去匹配二叉树边上标记的0和1