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 LinkedListtoList(){ 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( Listlist ){ // 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(); }}