Huffman树的原理以及代码构建

我们的目标认识只是基础,代码实现是才是核心

1.Huffman树的定义:

        从树中一个结点到另一个结点的之间的分支构成两个结点之间的路径,路径上的分支数称为路径长度。那么树的路径长度就是从树根到每一个结点的路径之和。带权路径长度WPL最小的二叉树叫做Huffman树。

二叉树的WPL = 5 * 3 + 15 * 3 + 40 * 2 + 30 * 2 + 10 * 2 = 220

2.Huffman树的构建

        这还不是一棵Huffman树,我们需要以下几个步骤

1.先把有权值的叶子结点按照从小到大的顺序排列成一个有序序列:A5,E10,B15,D30,E40.

2.取头两个最小权值的结点作为一个新节点N1的两个子节点,注意我们通常以相对较小的是左孩子,这里A就是N1的左孩子,E为N1的右孩子。新节点的权值为;两个叶子的权值和 5 + 10 = 10.

                                                                                                         

 3.将N1替换成A与E,插入有序序列中,保持从小到大排列。即:N1(15),B15, D30,C40

 4.重复2的操作,将N1和B作为一个新节点N2的两个子节点。


5.将N2替换N,与B,插入有序序列中,保持从小到大排列。即: N230, D30C40。

6.重复步骤2。将N2与D作为一个新节点N3的两个子结点。N3的权值=30+30=60。



7.将N3替换N2与D,插入有序序列中,保持从小到大排列。即: C40, N360。

8.重复步骤2。将C与Ngs作为1个新节点T的两个子结点。由于T即是根结点,完成赫夫曼树的构造。

此时带权路径长度 WPL = 40 * 1 + 30 * 2 + 15 * 3 + 10 * 4 +5 * 4 = 205 < 220 huffman树。

Huffman编码只需要把左孩子权值写成0,右孩子写成1,然后从根节点到叶子经过的路径就是它的编码。

 A:1000        B:101        C:0        D:11        E:1001

3.代码实现


package datastructure.tree;

import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;

public class Huffman {

	/** 用来存放节点值 */
	private static LinkedList<HuffNode> huffList = new LinkedList<HuffNode>();
	
	public static void main(String[] args) {
		//输入数据
		System.out.println("先输入数据个数回车,在输入数据");
		System.out.println("请输入: ");
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for (int i = 0; i < n; i++) {
			//数据输入控制循环
			huffList.add(new Huffman().new HuffNode(sc.next(),sc.nextInt() ));
		}
		huffmanCode();
		decode(huffList.get(0), "");
	}
	
	class HuffNode implements Comparable<HuffNode> {
		/** 权值 */
		int value;
		String name;
		/** 左孩子节点 */
		HuffNode lChild = null;
		/** 右孩子节点 */
		HuffNode rChild = null;
		/*
		 * 构造方法,用于输入初始化Huffman结点
		 */
		public HuffNode(String name, int value) {
			this.value = value;
			this.name = name;
		}
		//构建Huffman树时的构造方法
		public HuffNode(HuffNode lChild, HuffNode rChild) {
			this.lChild = lChild;
			this.rChild = rChild;
			// 权值之和,即合并两个叶子节点
			this.value = lChild.value + rChild.value;
		}
		/**********************
		* @param next
		* @param nextInt
		*********************
		*/
		/**
		 * 重新写比较方法
		 */
	    public int compareTo(HuffNode o) {
	    	if (this.value < o.value) {
	    		return -1;
	    	} else if (this.value == o.value) {
	    		return 0;
	    	} else {
	    		return 1;
	    	}
	    }
	}
	
	//Huffman树构建和编码
	public static void huffmanCode() {
		/*
		 * 当所剩结点为一时构造Huffman树成功
		 * 否则执行循环直到Huffman树的结点为一结束
		 */
		if (huffList.size() == 1) {
			return ;
		}
		while (huffList.size() > 1) {
			// 排序
			Collections.sort(huffList);
			// 将前两个节点进行合并
			HuffNode node = new Huffman().new HuffNode(huffList.get(0), huffList.get(1));
			// 删除前两个节点
			huffList.remove();
			huffList.remove();
			// 将新生成的节点添加到列表中
			huffList.add(node);
		}
		// 编码完成后,此时huffList中只剩一个根节点
	}
	
	//解码方法,我们的编码是叶子结点,所以当左右孩子为空时就输出
	public static void decode(HuffNode n, String code) {
		if ((n.lChild == null) && (n.rChild == null)) {
			// 叶子节点, 此时输出其对应编码
			System.out.print(n.name + "--->" + code);
			System.out.println();
			return ;
		}
		// 遍历左子树
		decode(n.lChild, code + "0");
		// 遍历右子树
		decode(n.rChild, code + "1");
		return ;
	}
}

 测试数据:

5
A 5
B 15
C 40
D 30
E 10

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉搜索(Binary Search Tree)是一种特殊的二叉,它满足以下两个条件: 1. 左子上所有节点的值均小于根节点的值。 2. 右子上所有节点的值均大于根节点的值。 这种特殊的结构使得我们可以非常高效地进行查找、插入和删除操作。 在 Python 中,我们可以使用类来实现二叉搜索。一个二叉搜索的节点一般包含一个值、指向左子的指针和指向右子的指针。我们可以定义一个 `Node` 类来表示一个节点,再定义一个 `BinarySearchTree` 类来表示整个。具体实现可以参考以下代码: ```python class Node: def __init__(self, value): self.value = value self.left = None self.right = None class BinarySearchTree: def __init__(self): self.root = None def insert(self, value): node = Node(value) if self.root is None: self.root = node else: current = self.root while True: if value < current.value: if current.left is None: current.left = node return else: current = current.left else: if current.right is None: current.right = node return else: current = current.right def search(self, value): current = self.root while current is not None: if current.value == value: return True elif value < current.value: current = current.left else: current = current.right return False def delete(self, value): parent = None current = self.root while current is not None: if current.value == value: # 如果当前节点没有左右子 if current.left is None and current.right is None: if parent is None: self.root = None elif parent.left == current: parent.left = None else: parent.right = None # 如果当前节点只有左子或只有右子 elif current.left is None: if parent is None: self.root = current.right elif parent.left == current: parent.left = current.right else: parent.right = current.right elif current.right is None: if parent is None: self.root = current.left elif parent.left == current: parent.left = current.left else: parent.right = current.left # 如果当前节点既有左子又有右子 else: successor = current.right successor_parent = current while successor.left is not None: successor_parent = successor successor = successor.left current.value = successor.value if successor_parent.left == successor: successor_parent.left = successor.right else: successor_parent.right = successor.right return elif value < current.value: parent = current current = current.left else: parent = current current = current.right ``` Huffman Huffman Tree)是一种用于数据编码的形结构。它可以根据数据的出现频率构建一个最优编码方案,从而实现数据的高效压缩。在 Huffman 中,出现频率较高的数据节点会被放到的上层,出现频率较低的数据节点则会被放到的下层。 在 Python 中,我们可以使用类来实现 Huffman 。一个 Huffman 的节点一般包含一个权值、指向左子的指针和指向右子的指针。我们可以定义一个 `Node` 类来表示一个节点,再定义一个 `HuffmanTree` 类来表示整个。具体实现可以参考以下代码: ```python class Node: def __init__(self, value, freq): self.value = value self.freq = freq self.left = None self.right = None class HuffmanTree: def __init__(self, data): self.root = None self.leaves = [] self.build_tree(data) def build_tree(self, data): freq = {} for c in data: freq[c] = freq.get(c, 0) + 1 nodes = [Node(c, f) for c, f in freq.items()] self.leaves = nodes[:] while len(nodes) > 1: nodes.sort(key=lambda n: n.freq) left = nodes.pop(0) right = nodes.pop(0) parent = Node(None, left.freq + right.freq) parent.left = left parent.right = right nodes.append(parent) self.root = nodes[0] def encode(self, data): code = {} for leaf in self.leaves: path = [] current = leaf while current is not self.root: parent = self._get_parent(current) if current is parent.left: path.append('0') else: path.append('1') current = parent path.reverse() code[leaf.value] = ''.join(path) encoded = ''.join([code[c] for c in data]) return encoded, code def decode(self, encoded, code): data = [] current = self.root for bit in encoded: if bit == '0': current = current.left else: current = current.right if current.value is not None: data.append(current.value) current = self.root decoded = ''.join(data) return decoded def _get_parent(self, node): if node is self.root: return None current = self.root while True: if current.left is node or current.right is node: return current elif node.freq < current.freq: current = current.left else: current = current.right ``` 以上就是基于 Python 实现二叉搜索Huffman 原理代码实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值