博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二叉树算法笔记:赫夫曼树(最优二叉树) in java
阅读量:6588 次
发布时间:2019-06-24

本文共 4899 字,大约阅读时间需要 16 分钟。

hot3.png

二叉树结点类,注:包含toArray()方法和toList()方法:
public class BinaryTreeNode {		private BinaryTreeNode leftChild;	private BinaryTreeNode rightChild;	private BinaryTreeNode parent;	private int value;	private String name;		public BinaryTreeNode(){	}	public BinaryTreeNode( int value ){		this.value = value;	}	public BinaryTreeNode( String name , int value ){		this.name = name;		this.value = value;	}		public BinaryTreeNode getLeftChild() {		return leftChild;	}	public void setLeftChild(BinaryTreeNode leftChild) {		this.leftChild = leftChild;	}	public BinaryTreeNode getRightChild() {		return rightChild;	}	public void setRightChild(BinaryTreeNode rightChild) {		this.rightChild = rightChild;	}	public int getValue() {		return value;	}	public void setValue(int value) {		this.value = value;	}	public BinaryTreeNode getParent() {		return parent;	}	public void setParent(BinaryTreeNode parent) {		this.parent = parent;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}		public LinkedList
toList(){ LinkedList
list = new LinkedList
(); toList( this , list ); return list; } private void toList( BinaryTreeNode root , List
list ){ if( root != null ){ list.add( root ); toList( root , list ); toList( root , list ); } } public int[] toArray(){ int[] array = new int[BinaryTree2Links.getSubNodeNum(this) + 1 ]; toArray( this , array , 0 ); return array; } private void toArray( BinaryTreeNode root , int[] array, int i ){ if( root != null ){ array[i++] = root.getValue(); toArray( root , array , i ); toArray( root , array , i ); } }}

 

 

 

 

Huffman树操作类:

/** * 赫夫曼树(最有二叉树):权值最大的叶子离根较近,权值小的结点离根较远。总的来讲就是,常用的能较快找到,难用的稍微麻烦点。 * 注:其定义符合国际上对满二叉树的定义,即要么有俩孩子,要么没孩子。但是不符合国内对满二叉树的定义(一片神奇的国土)。 * @author CheN * */public class HuffmanTree{		/**	 * 将一棵树转化为赫夫曼树	 * @param list	 * @return	 */	public static BinaryTreeNode buildHuffmanTree( BinaryTreeNode root ){		return buildHuffmanTree(root.toList());	}		/**	 * 建立赫夫曼树	 * @param list	 * @return	 */	public static BinaryTreeNode buildHuffmanTree( List
list ){ // 1.n个有权值结点,要求左右子树均为空 for( BinaryTreeNode node : list ){ if( node.getLeftChild() != null || node.getRightChild() != null || node.getParent() != null ) return null; } //4.重复步骤2-3,直至list中只剩下一棵树,即root。 while( list.size() > 1 ){ //2.找出值最小的两个结点,并且创建他们的父结点,权值为两个结点的和 //3.将两个旧结点抛除在外,将新建立的结点加入至list int min1 = findMinNode(list); BinaryTreeNode rightChild = list.remove( min1 ); int min2 = findMinNode(list); BinaryTreeNode leftChild = list.remove( min2 ); BinaryTreeNode newNode = buildNewNode(leftChild, rightChild); list.add(newNode); } return list.get(0); } /** * 查找权值最小的结点(运行两次,分别找出最小的两个) * @param list * @return */ private static int findMinNode( List
list ){ int index = 0; int min = list.get(0).getValue(); for( int i = 1 ; i < list.size(); i++ ){ if( list.get(i).getValue() < min ){ min = list.get(i).getValue(); index = i; } } return index; } /** * 创建新结点 * @param leftChild * @param rightChild * @return */ private static BinaryTreeNode buildNewNode( BinaryTreeNode leftChild , BinaryTreeNode rightChild ){ BinaryTreeNode newNode = new BinaryTreeNode(); newNode.setLeftChild(leftChild); newNode.setRightChild(rightChild); newNode.setValue(leftChild.getValue() + rightChild.getValue()); return newNode; } //赫夫曼编码// /** * 获取赫夫曼编码 */ public static Map
getHuffmanCoding( BinaryTreeNode root ){ Map
map = new HashMap
(); buildHuffmanCoding( root , map , "" ); return map; } /** * 生成每个内容对应的编码 * @param node * @param map * @param content */ private static void buildHuffmanCoding(BinaryTreeNode node, Map
map, String content) { if (node.getLeftChild() == null) { map.put(node.getName(), content);// 注意啦!!!下面这一行是为了让代码可解码,所以将map中设置成key/value + value/key的形式。如果不需要就注释掉即可(正常情况下不会造成bug,除非极特殊情况下)。 map.put(content, node.getName()); return; } // 对左子树分配代码"0" buildHuffmanCoding(node.getLeftChild(), map, content + "0"); // 对右子树分配代码"1" buildHuffmanCoding(node.getRightChild(), map, content + "1"); } /** * 用赫夫曼编码对内容进行编码 * @param str * @param map * @return */ public static String encoding( String str , Map
map ){ StringBuffer sb = new StringBuffer(); for( int i = 0 ; i < str.length() ; i++ ){ sb.append(map.get(str.substring(i, i+1))); } return sb.toString(); } /** * 用赫夫曼编码对编码过的内容进行解码(map中须包含解码信息,请注意buildHuffmanCoding方法中第4-5行) * @param str * @param map * @return */ public static String decoding( String str , Map
map ){ StringBuffer sb = new StringBuffer(); for( int i = 1 , j = 0 ; i < str.length() ; i++ ){ String code = str.substring( j , i ); boolean tag = map.containsValue(code); if( tag ){ j = i; sb.append(map.get(code)); } } return sb.toString(); }}

 

 

 

转载于:https://my.oschina.net/wangchen881202/blog/195167

你可能感兴趣的文章
UIPageControl 分页
查看>>
failed: Can’t locate DBD/mysql.pm的解决办法
查看>>
C#二进制流的序列化和反序列化操作
查看>>
XIB的是用
查看>>
ORACLE 10G RAC 10.2.0.5 删除节点
查看>>
PHP连接MongoDB
查看>>
Learning Data Structure_2_线性表、栈和队列
查看>>
JavaFx系列(二) Thread顯示進度窗的對話框
查看>>
Servlet获取全路径
查看>>
BAT频繁与移动医疗挂钩 预示行业即将爆发?
查看>>
我的友情链接
查看>>
制作JD的手动和自动轮播图片板块
查看>>
SQLite第九课 sqlite3_set_authorizer案例
查看>>
iconv 用法
查看>>
Redis应用实践:小红书海量Redis存储之道
查看>>
mii-tool查看网卡状态
查看>>
驱动外置+原版安装方式『XLOS_Windows8_Pro_X86纯净版_V1.0』
查看>>
php操作memcache的使用测试总结
查看>>
Oracle创建表语句(Create table)语法详解及示例
查看>>
如何利用系统自带的小工具制作特殊字符
查看>>