基本知识: 树:一个结点下分成多个子结点,最上面的结点称为根结点(拥有倒立的树的形状)。 二叉树:一个结点下有且仅有左右两个子结点。 哈弗曼树:又称最优二叉树,是一类带权路径最短的树。 结点之间的路径长度:从一个结点到另一个结点之间的分支数目。 树的路径长度:从树的根到树中每一个结点的路径长度之和。 结点的带权路径长度:从该结点到树根之间的路径长度与结点上权的乘积。 树的带权路径长度:树中所有叶子结点的带权路径长度之和。 计算机专业的同学应该都会学习《离散数学》,《离散数学》中就有哈弗曼树的构造和哈弗曼树的编码,可是即便是这样,要用java实现起来还是会有一定难度的。。。 哈弗曼树的构造: 1.根据给定的n个权值{w1,w2,...wn}构造n棵二叉树的集合F={T1,T2,...Tn},其中Ti中只有一个权值为wi的根结点,左右子树为空; 2.在F中选取两棵根结点的权值为最小的数作为左、右子树以结构一棵新的二叉树,且置新的二叉树的根结点的权值为左、右子树上根结点的权值之和; 3.将新的二叉树加入到F中,删除原两棵根结点权值最小的树; 4.重复2和3直到F中只含有一棵树为止,这棵树就是哈弗曼树。 哈弗曼树的编码: 从哈弗曼树的根结点开始,对左子树分配代码“0”,对右子树分配代码“1”,一直到达叶子结点为止,然后将从树根沿每条路径到达叶子结点的代码排列起来,便得到了哈弗曼编码。 [size=medium][color=blue]构建二叉树:[/color][/size] package 二叉树; //主函数 import java.util.Random; public class Manage { /** * @param args */ public static void main(String[] args) { Nodetree nt = new Nodetree(); Random rand = new Random(); for(int i=0;i<10;i++){ Node node =new Node(rand.nextInt(100)); nt.add(node); System.out.print(node.getData()+" "); } System.out.println(" "); System.out.println("前序遍历:"); nt.preorder(nt.getRoot()); System.out.println(" "); System.out.println("中序遍历:"); nt.inorder(nt.getRoot()); System.out.println(" "); System.out.println("后序遍历:"); nt.postorder(nt.getRoot()); System.out.println(" "); //节点的删除 // System.out.println("删除后的前序遍历:"); // nt.deleteNode(nt.getRoot().getRight()); // nt.preorder(nt.getRoot()); } } package 二叉树; public class Node { //结点数据 private int data; //左子树结点 private Node left; //右子树结点 private Node right; //父节点 private Node parent; //构造方法 int i;//用于记录此结点的值在数组中存放的位置 public Node(){ } public Node(int data){ this.data=data; } public Node(int data,Node left,Node right,Node parent){ this.data=data; this.left=left; this.right=right; this.parent=parent; } public Node getParent() { return parent; } public void setParent(Node parent) { this.parent = parent; } public void Print(){ System.out.print(this.data+" "); } public int getData() { return data; } public void setData(int data) { this.data = data; } public Node getLeft() { return left; } public void setLeft(Node left) { this.left = left; } public Node getRight() { return right; } public void setRight(Node right) { this.right = right; } } package 二叉树; public class Nodetree { private Node root;// 根节点 /** * 添加节点的方法 */ public void add(Node node) { // 判断root是否为null if (null == root) { root = node; }else{ queryNode(root,node); } } /** * 查找节点的方法 * @param node1根节点 * @param node2要被添加的节点 * @return 返回要添加节点的位置 */ private void queryNode(Node node1,Node node2){ if(node2.getData() > node1.getData()){ if(node1.getRight() != null){ queryNode(node1.getRight(),node2); }else{ node1.setRight(node2); } }else{ if(node1.getLeft() != null){ queryNode(node1.getLeft(),node2); }else{ node1.setLeft(node2); } } } // /** // * 删除结点的方法(额。。。这个方法暂时还没弄好) // * @param node要删除的节点 // */ // public void deleteNode(Node node){ // if(node!=null){ // if(node.getLeft()==null){ // node=null; // } // else if(node.getRight()==null){ // node=node.getLeft(); // node.setLeft(null); // } // else{ // node=null; // } // } // else{ // return; // } // } public Node getRoot() { return root; } public void setRoot(Node root) { this.root = root; } /** * 遍历结点的方法 * @param node */ //前序遍历: public void preorder(Node node) { if (node != null) { visit(node); preorder(node.getLeft()); preorder(node.getRight()); } } //中序: public void inorder(Node node) { if (node != null) { inorder(node.getLeft()); visit(node); inorder(node.getRight()); } } //后序: public void postorder(Node node) { if (node != null) { postorder(node.getLeft()); postorder(node.getRight()); visit(node); } } public void visit(Node node) { System.out.print(node.getData()+" "); } } [size=medium][color=blue]哈弗曼树:[/color][/size] 见压缩包中