赫夫曼树精析

赫夫曼树

定义:给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径(wpl)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树


赫夫曼树是带权路径长度最短的树,权值较大的节点离跟越近

路径: 从一个节点到另一个节点的分支构成

路径长度: 从树中某个节点到另一个节点之间的分支数目

权: 树中节点相关的数值

带权路径长度: 从根开始,从根开始,路径长度 * 权值;

树的带权路径长度: 树中所有叶节点的带权路径长度之和成为该树的带权路径长度

哈夫曼树: 带权路径最小的树


构成赫夫曼树的步骤

1.从小到大排序,将每一个数据,每个数据都是一个节点,每个节点可以看成是一个最简单的二叉树
2.取出根节点权值最小的两颗二叉树
3.组成一颗新的二叉树,该新的二叉树的根节点是前面两颗二叉树根节点权值之和
4.再将这颗新的二叉树,以根节点的权值大小,再次排序,不断重复 1-2-3- 4的步骤,直到数列众所有的数据都被处理掉,就得到一颗赫夫曼树。


图示

1.对这些散树排序

赫夫曼树精析_第1张图片
2.取出根节点最小的两个树组成一颗新树,再排序

1>

赫夫曼树精析_第2张图片
2>
赫夫曼树精析_第3张图片
3>

赫夫曼树精析_第4张图片
4>

赫夫曼树精析_第5张图片

5>

赫夫曼树精析_第6张图片
6>

赫夫曼树精析_第7张图片
7>

赫夫曼树精析_第8张图片
8>

赫夫曼树精析_第9张图片


话不多说上代码
package mzy.tree_b;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class HuffmanTree {
	public static void main(String[] args) {
		int[] arr = { 13, 7, 8, 3, 29, 6, 1 };
		NumNode resnNode = creHTree(arr);
		preOrder(resnNode);
		// 前序遍历

	}

	// 前序遍历
	public static void preOrder(NumNode root) {
		if (root != null) {
			root.preOder();
		} else {
			System.out.println("根节点为空!");
		}

	}

	// 创建赫夫曼树

	public static NumNode creHTree(int[] arr) {

		// 为了操作方便
		// 1.遍历数组
		// 2.将arr的每一个元素构建成一个NumNode
		// 3.将NumNode放入到ArrayList中

		List<NumNode> nodes = new ArrayList<NumNode>();
		for (int value : arr) {
			nodes.add(new NumNode(value));
		}
		Collections.sort(nodes);
		System.out.println("paixi:" + nodes);

		// 取出权值最小的二叉树
		while (nodes.size() != 1) {
			// 排序从小到大
			Collections.sort(nodes);
			// 取出权值最小的值左右值
			NumNode leftNode = nodes.get(0);
			NumNode rightNode = nodes.get(1);

			// 构建一颗二叉树
			NumNode parent = new NumNode(leftNode.value + rightNode.value);
			parent.Nleft = leftNode;
			parent.Nright = rightNode;
			// 删除集合里的二叉树
			nodes.remove(leftNode);
			nodes.remove(rightNode);
			// 将新节点放进集合里
			nodes.add(parent);
		}

		System.out.println("paixi:" + nodes);
		return nodes.get(0);
	}

}

//创建节点类
class NumNode implements Comparable<NumNode> {
	int value;// 节点
	NumNode Nleft;// 左子节点
	NumNode Nright;// 右子节点

	public NumNode(int value) {
		this.value = value;
	}

	public String toString() {
		return "NumNode [value=" + value + "]";
	}

	public int compareTo(NumNode n) {
		// 表示从小到达排序
		return this.value - n.value;
	}

	public void preOder() {
		System.out.println(this);
		if (this.Nleft != null) {
			this.Nleft.preOder();
		}
		if (this.Nright != null) {
			this.Nright.preOder();
		}
	}

}


你可能感兴趣的:(数据结构)