哈弗曼树及其操作

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 HuffmanNode(int weight){
12         this.weight=weight;
13         flag=0;
14         parent=lchild=rchild=null;
15     }
16 }

点击可复制代码

 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 HuffmanNode(int weight){
12         this.weight=weight;
13         flag=0;
14         parent=lchild=rchild=null;
15     }
16 }

点击+可复制代码

2.哈夫曼编码的构建及测试

 1 package com.neusoft.Tree;
 2 /**
 3  * @author zhao-chj
 4  * 哈夫曼树及其操作
 5  */
 6 public class HuffmanTree {
 7
 8     //求哈夫曼编码的算法,w存放n个字符的权值
 9     public int[][] huffmanCoding (int[] w){
10         int n= w.length;//哈夫曼树的字符个数
11         int m=2*n-1;//哈夫曼树的节点个数
12         HuffmanNode[] HN =new HuffmanNode[m];
13         int i=0;
14         for (i = 0;  i< n; i++) {
15             HN[i] = new HuffmanNode(w[i]);//构造n个具有权值的节点
16         }
17         for (i = n;  i< m; i++) {
18             HuffmanNode min1=selectMin(HN,i-1);
19             min1.flag=1;//表示已标记
20             HuffmanNode min2=selectMin(HN, i-1);
21             min2.flag=1;
22             //构造min1和min2的父节点,并且修改权值
23             HN[i] =new HuffmanNode();
24             min1.parent=HN[i];
25             min2.parent=HN[i];
26             HN[i].lchild=min1;
27             HN[i].rchild=min2;
28             HN[i].weight=min1.weight+min2.weight;
29         }
30         //从叶子节点到根逆向求每个字符的哈夫曼编码
31         int[][] HuffCode =new int[n][n];//分配n个字符编码存储空间
32         for (int j = 0; j <n; j++) {
33             int start=n-1;//编码的开始位置,初始化为数组的结尾
34             for (HuffmanNode c=HN[j],p=c.parent; p!=null; c=p,p=p.parent) {
35                 //从叶子结点到根逆向求解编码
36                 if (p.lchild.equals(c)) {//左孩子编码为0
37                     HuffCode[j][start--] =0;
38                 }else {
39                     //右孩子编码为1
40                     HuffCode[j][start--]=1;
41                 }
42                 HuffCode[j][start]=-1;//编码的开始标志为-1
43             }
44         }
45         return HuffCode;
46     }
47     /**
48      * 在HN[0...i-1]选择不再哈夫曼树中且weight最小的节点
49      */
50     private HuffmanNode selectMin(HuffmanNode[] HN, int end) {
51         HuffmanNode min=HN[end];
52         for (int i = 0; i < end; i++) {
53             HuffmanNode h=HN[i];
54             if (h.flag==0&&h.weight<min.weight) {
55                 //不再哈夫曼树中且weight最小的节点
56                 min=h;
57             }
58         }
59         return min;
60     }
61     public static void main(String[] args) {
62         int [] w={23,11,5,3,29,14,7,8};
63         HuffmanTree T =new HuffmanTree();//构造哈夫曼树
64         int [][] HN=T.huffmanCoding(w);//求哈夫曼编码
65         System.out.println("哈夫曼编码为:");
66         for (int i = 0; i < HN.length; i++) {
67             System.out.print(w[i]+" ");
68             for (int j = 0; j < HN[i].length; j++) {
69                 if (HN[i][j] ==-1 ) {//数组结尾标志
70                     for (int k = j+1; k < HN[i].length; k++) {
71                         System.out.print(HN[i][k]);
72                     }
73                     break;
74                 }
75             }
76             System.out.println();
77         }
78     }
79 }

点击可复制代码

 1 package com.neusoft.Tree;
 2 /**
 3  * @author zhao-chj
 4  * 哈夫曼树及其操作
 5  */
 6 public class HuffmanTree {
 7
 8     //求哈夫曼编码的算法,w存放n个字符的权值
 9     public int[][] huffmanCoding (int[] w){
10         int n= w.length;//哈夫曼树的字符个数
11         int m=2*n-1;//哈夫曼树的节点个数
12         HuffmanNode[] HN =new HuffmanNode[m];
13         int i=0;
14         for (i = 0;  i< n; i++) {
15             HN[i] = new HuffmanNode(w[i]);//构造n个具有权值的节点
16         }
17         for (i = n;  i< m; i++) {
18             HuffmanNode min1=selectMin(HN,i-1);
19             min1.flag=1;//表示已标记
20             HuffmanNode min2=selectMin(HN, i-1);
21             min2.flag=1;
22             //构造min1和min2的父节点,并且修改权值
23             HN[i] =new HuffmanNode();
24             min1.parent=HN[i];
25             min2.parent=HN[i];
26             HN[i].lchild=min1;
27             HN[i].rchild=min2;
28             HN[i].weight=min1.weight+min2.weight;
29         }
30         //从叶子节点到根逆向求每个字符的哈夫曼编码
31         int[][] HuffCode =new int[n][n];//分配n个字符编码存储空间
32         for (int j = 0; j <n; j++) {
33             int start=n-1;//编码的开始位置,初始化为数组的结尾
34             for (HuffmanNode c=HN[j],p=c.parent; p!=null; c=p,p=p.parent) {
35                 //从叶子结点到根逆向求解编码
36                 if (p.lchild.equals(c)) {//左孩子编码为0
37                     HuffCode[j][start--] =0;
38                 }else {
39                     //右孩子编码为1
40                     HuffCode[j][start--]=1;
41                 }
42                 HuffCode[j][start]=-1;//编码的开始标志为-1
43             }
44         }
45         return HuffCode;
46     }
47     /**
48      * 在HN[0...i-1]选择不再哈夫曼树中且weight最小的节点
49      */
50     private HuffmanNode selectMin(HuffmanNode[] HN, int end) {
51         HuffmanNode min=HN[end];
52         for (int i = 0; i < end; i++) {
53             HuffmanNode h=HN[i];
54             if (h.flag==0&&h.weight<min.weight) {
55                 //不再哈夫曼树中且weight最小的节点
56                 min=h;
57             }
58         }
59         return min;
60     }
61     public static void main(String[] args) {
62         int [] w={23,11,5,3,29,14,7,8};
63         HuffmanTree T =new HuffmanTree();//构造哈夫曼树
64         int [][] HN=T.huffmanCoding(w);//求哈夫曼编码
65         System.out.println("哈夫曼编码为:");
66         for (int i = 0; i < HN.length; i++) {
67             System.out.print(w[i]+" ");
68             for (int j = 0; j < HN[i].length; j++) {
69                 if (HN[i][j] ==-1 ) {//数组结尾标志
70                     for (int k = j+1; k < HN[i].length; k++) {
71                         System.out.print(HN[i][k]);
72                     }
73                     break;
74                 }
75             }
76             System.out.println();
77         }
78     }
79 }

点击+可复制上述代码

3.测试及运行结果

时间: 2024-10-21 01:41:25

哈弗曼树及其操作的相关文章

哈弗曼树的建立

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

【哈弗曼树】HDU 5350 MZL&#39;s munhaff function

通道 题意:根据那个递推式,找找规律即可. 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; typedef long long ll; inline bool rd(int &ret) { char c; int sgn; if(c = getchar(

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

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

java实现哈弗曼树

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

poj 3253 Fence Repair 【哈弗曼树】+【优先队列】

Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27742   Accepted: 9019 Description Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000)

数据结构&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+

(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树

写了一点haffman树的创建和二叉树的非递归遍历. 如果编写代码的时候出现了,思维断点,可以借鉴一下, 避免浪费一些不必要的时间. 我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占 位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我 是占位符我是占位符我是占位符我是占位符我是占位符我是 占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符

简单哈弗曼树(Java)

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

求哈弗曼树的编码

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