实现Huffman树

原创 2016年08月30日 11:13:10

为了使得WPL即带权的外部结点路径最小,基本原则是:让权值大的结点离根近一些,权值小的结点离根远一些。实现方法:每次从未加入到树中的结点中选择两个权值最小的,即去权值最小和次小的结点作为左右子结点产生父结点,父结点的权值为这两个结点的权值之和,然后将父结点取代这两个结点带回去,继续循环。用数组作为存储结构。假定给定的外部结点权值数组中有m个元素,即有m个外部结点,那么内部结点就应该有m - 1个,创建一个容量为2 * m - 1的数组存放所有的结点,先用外部结点的权值初始化数组的前m个元素,然后循环填充后面的m - 1个元素,每次都是从第i个位置的前面查找没有加入树的最小和次小结点,形成一个新的结点,作为它们的父结点作为第m + i个结点元素。最后,设置根结点便可以得到这棵Huffman树。

直接上代码:

import java.util.LinkedList;
import java.util.Queue;


class HuffmanNode { //哈弗曼树中结点的数据结构
int w; //保存每个结点的权值

HuffmanNode left;
HuffmanNode right;
HuffmanNode parent;

public HuffmanNode(int w) {
this.w = w;
this.left = null;
this.right = null;
this.parent = null;
}
}


class HuffmanTree {
HuffmanNode root;
int n;

public HuffmanTree(int wA[]) {
int m = wA.length;
this.n = 2 * m - 1;
HuffmanNode hnA[] = new HuffmanNode[n];

for(int i = 0; i < m; i++) {
hnA[i] = new HuffmanNode(wA[i]); //初始化前m个结点
}

int min, scMin, i_min, i_scMin; //用来保存权值最小和次小的结点的权值和下标
for(int i = 0; i < m - 1; i++) {
min = scMin = Integer.MAX_VALUE; i_min = i_scMin = 0;
for(int j = 0; j < m + i; j++) { //每次从数组中第一个元素开始当前位置的前一个元素中进行查找
if(hnA[j].parent == null) {//这里的hnA[j].parent == null代表在未加入到树中的结点中查找

/*

*这里用到了一个时间复杂度为o(n)的查找最小元素和次小元素的技巧:如果当前元素比当前最小值小,那么更新次小值为当前最小值,最小值为当前值,否 *则,再与当前次小值进行比较,如果比次小值小,则更新次小值为当前元素。

*/
if(hnA[j].w < min) {
scMin = min;
i_scMin = i_min;
min = hnA[j].w;
i_min = j;
}
else {
if(hnA[j].w < scMin) {
scMin = hnA[j].w;
i_scMin = j;
}
}
}
}
hnA[m + i] = new HuffmanNode(min + scMin);
hnA[m + i].left = hnA[i_min];
hnA[m + i].right = hnA[i_scMin];
hnA[i_min].parent = hnA[i_scMin].parent = hnA[m + i];
}

root = hnA[n - 1];
}

public void print() {//这里实现了二叉树的层次换行打印,基本思想就是设置两个代表当前层和下一层结点数目的变量。
if(root == null)
return;
Queue<HuffmanNode> queue = new LinkedList<HuffmanNode>();

queue.offer(root);
HuffmanNode p;
int currNodes = 1, nextNodes = 0;
while(!queue.isEmpty()) {
p = queue.poll();
System.out.print(p.w + "\t");
currNodes--;

if(p.left != null) {
queue.offer(p.left);
nextNodes++;
}

if(p.right != null) {
queue.offer(p.right);
nextNodes++;
}

if(currNodes == 0) {//先统计下一层,再判断
System.out.println();
currNodes = nextNodes;
nextNodes = 0;
}
}
}
}


public class TestHuffmanTree {


public static void main(String[] args) {
int wA[] = {2,3,5,7,11,13,17,19,23,29,31,37,41};
HuffmanTree ht = new HuffmanTree(wA);
ht.print();
}


}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C语言实现Huffman树

  • 2016年12月20日 09:56
  • 124KB
  • 下载

HUFFMAN树的C++实现

  • 2010年05月10日 20:42
  • 7KB
  • 下载

【小项目】用Huffman树实现文件压缩并解压

一、前言         如果你学习数据结构,就一定会学到Huffman树,而Huffman编码实际上上就是zip压缩的核心部分,所以,如果已经学习了Huffman树,为何不尝试写一个压缩程序出来呢?...

Huffman树的C++模板类实现

  • 2016年10月28日 23:00
  • 5KB
  • 下载

huffman 二叉树实现

  • 2013年06月03日 13:48
  • 499KB
  • 下载

huffman(哈夫曼)树的实现

哈夫曼树的实现 概念: 哈夫曼(Huffman)树又称最优二叉树或最优搜索树,是一种带权路径长度最短的二叉树。在许多应用中,常常赋给树中结点一个有某种意义的实数,称此实数为该结点的权。从树根结点到该...
  • curson_
  • curson_
  • 2016年12月21日 00:12
  • 334

Huffman树的实现

  • 2015年06月17日 21:38
  • 294B
  • 下载

[C语言]哈夫曼树(Huffman)的构造与实现

C语言编程数据结构中的哈弗曼树是非常重要的,哈夫曼主要是它的编码应用可以保证译码的非二义性。 每天坚持编写一个程序,持之以恒,我们就会更加熟练的进行编程,从而为以后打下基础。 下面是...

Huffman树及编码C++实现

Huffman树及编码C++实现                                         By qianghaohao(Johar)                    H...

huffman树( c++) 的三种实现

今天转一篇huffman树的实现代码 原文链接:http://www.icourse163.org/learn/zju-93001#/learn/forumdetail?pid=532240 还有...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:实现Huffman树
举报原因:
原因补充:

(最多只允许输入30个字)