Bootstrap

HuffmanTree(最优二叉树)

基本知识:
树:一个结点下分成多个子结点,最上面的结点称为根结点(拥有倒立的树的形状)。
二叉树:一个结点下有且仅有左右两个子结点。
哈弗曼树:又称最优二叉树,是一类带权路径最短的树。
结点之间的路径长度:从一个结点到另一个结点之间的分支数目。
树的路径长度:从树的根到树中每一个结点的路径长度之和。
结点的带权路径长度:从该结点到树根之间的路径长度与结点上权的乘积。
树的带权路径长度:树中所有叶子结点的带权路径长度之和。
计算机专业的同学应该都会学习《离散数学》,《离散数学》中就有哈弗曼树的构造和哈弗曼树的编码,可是即便是这样,要用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]
见压缩包中
;