java 实现最优二叉树_哈夫曼树(最优二叉树) - Java实现

简介

哈夫曼树(Huffman)树又称最优二叉树,是指对于一组带有确定权值的叶子结点所构造的具有带权路径长度最短的二叉树。从树中一个结点到另一个结点之间的分支构成了两结点之间的路径,路径上的分支个数称为路径长度。二叉树的路径长度是指由根结点到所有叶子结点的路径长度之和。如果二叉树中的叶子结点都有一定的权值,则可将这一概念拓展:设二叉树具有n个带权值的叶子结点,则从根结点到每一个叶子结点的路径长度与该叶子结点权值的乘积之和称为二叉树路径长度,记做:

WPL = W1L1 + W2L2 + ...... + WnLn;

构建过程

① 对数据中出现过的元素各产生一个树叶节点,并赋予其出现的频率。

② 令N为T1和T2的父节点,其中T1和T2是出现频率最低的两个节点,令N的频率为T1和T2的频率之和

③ 消去两个节点,插入N节点,重复前面的步骤。

代码实现

HuffmanTree.java

import java.util.ArrayDeque;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

public class HaffmanTree {nodes;

private Node root;

// 实现排序接口,添加结点自动排序,从小到大排序

private int value;

private Node left;

private Node right;

public Node(int value) {

this.value = value;

}

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;

}

@Override

public int compareTo(Node o) {

return this.value - o.value;

}

}

public HaffmanTree {}

public void bulidHaffmanTree(int arr) {

nodes = new ArrayList<>;

for (int i = 0; i < arr.length; i++) {

nodes.add(new Node(arr[i]));

}

root = createHaffmanTree(nodes);

}nodes) {

while (nodes.size > 1) {

// 排序,每次取最小的两个结点

Collections.sort(nodes);

// 获得权值最小的两个结点,左结点大于右结点

Node leftChild = nodes.get(1);

Node rightChild = nodes.get(0);

// 生成新结点

Node newNode = new Node(leftChild.value + rightChild.value);

newNode.left = leftChild;

newNode.right = rightChild;

// 删除权值最小的两个结点

nodes.remove(0);

nodes.remove(0);

// 将新结点加入到集合中

nodes.add(newNode);

}

return nodes.get(0);

}

// 先序遍历

public void preOrder {

preOrder(root);

}

private void preOrder(Node root) {stack = new ArrayDeque<>;

while (root != null || !stack.isEmpty) {

System.out.println(root.value);

stack.push(root);

root = root.left;

}

if (!stack.isEmpty) {

root = stack.pop;

root = root.right;

}

}

// 中序遍历

public void inOrder {

preOrder(root);

}

private void inOrder(Node root) {

while (root != null || !stack.isEmpty) {

stack.push(root);

root = root.left;

}

if (!stack.isEmpty) {

root = stack.pop;

System.out.println(root.value);

root = root.right;

}

}

// 非递归后序遍历

public void postOrder {

postOrder(root);

}

private void postOrder(Node root) {

Node cur = root;

Node pre = null;

while (cur != null || !stack.isEmpty) {

while (cur != null) {

stack.push(cur);

cur = cur.left;

}

cur = stack.peek;

if (cur.right == null || cur.right == pre) {

System.out.print(cur.value + " ");

pre = cur;

stack.pop;

cur = null;

} else {

cur = cur.right;

}

}

}

// 层序遍历

public void levelOrder {

levelOrder(root);

}

private void levelOrder(Node root) {ArrayDequequeue = new ArrayDeque<>;

Node curr = root;

if (curr == null)

return;

queue.add(curr);

while (!queue.isEmpty) {

curr = queue.remove;

System.out.print(curr.value + " ");

if (curr.left != null)

queue.add(curr.left);

if (curr.right != null)

queue.add(curr.right);

}

}

}

测试代码

HuffmanTreeTest.java

public class HaffmanTreeTest {

public static void main(String args) {

int arr = {13, 7, 8, 3, 29, 6, 1};

HaffmanTree haffmanTree = new HaffmanTree;

haffmanTree.bulidHaffmanTree(arr);

haffmanTree.postOrder;

System.out.println;

haffmanTree.levelOrder;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
程序 = 数据结构 + 算法  程序是为了解决实际问题而存在的。然而为了解决问题,必定会使用到某些数据结构以及设计一个解决这种数据结构的算法。如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功。编程实战算法,不是念PPT,我们讲的就是实战与代码实现与企业应用。程序 = 数据结构 + 算法                ——图灵奖得主,计算机科学家N.Wirth(沃斯)作为程序员,我们做机器学习也好,做python开发也好,java开发也好。有一种对所有程序员无一例外的刚需 —— 算法与数据结构日常增删改查 + 粘贴复制 + 搜索引擎可以实现很多东西。同样,这样也是没有任何竞争力的。我们只可以粘贴复制相似度极高的功能,稍复杂的逻辑没有任何办法。语言有很多,开发框架更是日新月异3个月不学就落后我们可以学习很多语言,很多框架,但招聘不会考你用5种语言10种框架实现同一个功能。真正让程序员有区分度,企业招聘万年不变的重点 —— 算法与数据结构。算法代表程序员水平的珠穆朗玛。如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功。 想写出精炼、优秀的代码,不通过不断的锤炼,是很难做到的。 开这个系列的目的是为了自我不断积累。不积跬步无以至千里嘛。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值