ハフマンツリーとそのJava実装

:より転載詳細なグラフィックJAVAハフマン木

コンセプト

与えられたn個の重みのnとしてリーフノードツリーの加重経路の長さが最小に達した場合、二分木構造、例えば二分木もハフマン木(ハフマンツリー)として知られている最適なバイナリツリーと呼ばれます。ハフマンツリーは、最短経路長加重ツリー、近いルートノードから大きな重みです。

その構成を順次ツリーノードに底部で最小重量を選択する、単純で、新しいノードが新しいノードを構成する重みが2に等しくなければならないことに留意すべきで、最小の2つの接続を構成しますバック私たちはツリーのノードを構成する必要が新しいノードに入れ、その後、右ノード値とをソートするために続けて、ハフマンツリーは、すべての情報がノードがリーフノードで保存されるように構成しました上。

例:

文字列があります:aaaaaaaaaabbbbbaaaaaccccccccddddddfff

最初のステップは、の文字​​の重みと呼ばれる各文字が出現する回数を、数えてみましょう。:15、B:5、C:8、D:6、F:3。

第二のステップは、ノードを構築する2つの文字、B5及びF3の存在最小重量を求めます。

F3を除去し、今A15、C8、D6、FB8、B5。

唯一つのノードが構築されるまで、第3のステップは、第二の工程が繰り返されます。

それはdfb14、A15、C8です。

最後に、

[OK]を、私たちは、ハフマンツリーが完全に構築されます。 

注:オリジナルのツリーは通常の食事に示すように、右から構築を開始するには、ここに構築されたが、左から、下から上に構築するために開始する必要があり、Javaコードを以下に示し、最終的な出力の結果は、原則に従うことです。トラバーサル)

package com.gxu.dawnlab_algorithm7;

import java.util.ArrayList;

import com.gxu.dawnlab_algorithm3.PrintBinaryTree.Node;

/**
 * 哈夫曼数的实现
 * @author junbin
 *
 * 2019年7月11日
 */
public class Huffman {
	public static class Node{
		public String data;// 节点的数据
		public int count;// 节点的权值
		public Node lChild;
		public Node rChild;
		
		public Node() {	
		}
		
		public Node(String data, int count) {
			this.data = data;
			this.count = count;
		}
			 
		public Node(int count, Node lChild, Node rChild) {
			this.count = count;
			this.lChild = lChild;
			this.rChild = rChild;
		}
			 
		public Node(String data, int count, Node lChild, Node rChild) {
			this.data = data;
			this.count = count;
			this.lChild = lChild;
			this.rChild = rChild;
		}
	}
	
	private String str;// 最初用于压缩的字符串
	private String newStr = "";// 哈夫曼编码连接成的字符串 
	private Node root;// 哈夫曼二叉树的根节点
	private boolean flag;// 最新的字符是否已经存在的标签
	private ArrayList<String> charList;// 存储不同字符的队列:相同字符存在同一位置
	private ArrayList<Node> NodeList;// 存储节点的队列
	
	/**
	  * 构建哈夫曼树
	  * 
	  * @param str
	  */
	public void creatHfmTree(String str) {
		this.str = str;
		charList = new ArrayList<String>();
		NodeList = new ArrayList<Node>();
		// 1.统计字符串中字符以及字符的出现次数
		// 基本思想是将一段无序的字符串如ababccdebed放到charList里,分别为aa,bbb,cc,dd,ee
		// 并且列表中字符串的长度就是对应的权值
		for (int i = 0; i < str.length(); i++) {
			char ch = str.charAt(i); // 从给定的字符串中取出字符
			flag = true;
			for (int j = 0; j < charList.size(); j++) {
				if (charList.get(j).charAt(0) == ch) {// 如果找到了同一字符
					String s = charList.get(j) + ch;
					charList.set(j, s);
					flag = false;
					break;
				}
			}
			if (flag) {
				charList.add(charList.size(), ch + "");
			}
		}
		// 2.根据第一步的结构,创建节点
		for (int i = 0; i < charList.size(); i++) {
			String data = charList.get(i).charAt(0) + ""; // 获取charList中每段字符串的首个字符
			int count = charList.get(i).length(); // 列表中字符串的长度就是对应的权值
			Node node = new Node(data, count); // 创建节点对象
			NodeList.add(i, node); // 加入到节点队列
		}
	 
		// 3.对节点权值升序排序
		Sort(NodeList);
		while (NodeList.size() > 1) {// 当节点数目大于一时
			// 4.取出权值最小的两个节点,生成一个新的父节点
			// 5.删除权值最小的两个节点,将父节点存放到列表中
			Node left = NodeList.remove(0);
			Node right = NodeList.remove(0);
			int parentWeight = left.count + right.count;// 父节点权值等于子节点权值之和
			Node parent = new Node(parentWeight, left, right);
			NodeList.add(0, parent); // 将父节点置于首位
		}
		// 6.重复第四五步,就是那个while循环
		// 7.将最后的一个节点赋给根节点
		root = NodeList.get(0);
		output(root);
	 }
	 /**
	  * 升序排序
	  * 
	  * @param nodelist
	  */
	public void Sort(ArrayList<Node> nodelist) {
		for (int i = 0; i < nodelist.size() - 1; i++) {
			for (int j = i + 1; j < nodelist.size(); j++) {
				Node temp;
				if (nodelist.get(i).count > nodelist.get(j).count) {
					temp = nodelist.get(i);
					nodelist.set(i, nodelist.get(j));
					nodelist.set(j, temp);
				}
	 
			}
		}
	 
	}
	 
	 /**
	  * 先序遍历
	  * 
	  * @param node
	  *   节点
	  */
	public void output(Node head) {
		if(head == null){
			return;
		}
		System.out.print(head.count + " ");
		output(head.lChild);
		output(head.rChild);
	}
	 
	public void output() {
		output(root);
	}

	public static void main(String[] args) {
		Huffman huff = new Huffman();//创建哈弗曼对象
		huff.creatHfmTree("aaaaaaaaaabbbbbaaaaaccccccccddddddfff");//构造树
	}
}

予約限定トラバーサル結果出力は次のようになります。3722148356815。

公開された61元の記事 ウォンの賞賛9 ビュー30000 +

おすすめ

転載: blog.csdn.net/qq_33204444/article/details/95486372