主要使用自己上一篇文章中的自定义二叉树类实现了霍夫曼树,霍夫曼编码和讲一个数学算式建成树。
1.霍夫曼树和霍夫曼编码
霍夫曼树即最优二叉树,因为它每个叶子结点到根结点的距离与叶子结点的权值有关,往往此权值越大,它的路径越短,即带权路径长度要保持最小,所以叫它最优二叉树。
引用
(1)设给定的一组权值为{W1,W2,W3,……Wn},据此生成森林F={T1,T2,T3,……Tn},F 中的每棵二叉树只有一个带权为Wi的根节点(i=1,2,……n)。
算法思想为:
(2)在F中选取两棵根节点的权值最小和次小的二叉树作为左右构造一棵新的二叉树,新二叉树根节点的权值为其左、右子树根节点的权值之和。
(3)在F中删除这两棵最小和次小的二叉树,同时将新生成的二叉树并入森林中。
(4)重复(2)(3)过程直到F中只有一棵二叉树为止。
以下为代码:
结点类的补充
private String code = " ";
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
核心代码:
/**
* 按照传入的数组创建霍夫曼树的方法 通过优先队列实现
*
* @param arr
* 传入的整型数组
*/
public void creatHuffmanTree(int[] arr) {
if (arr == null) {
throw new RuntimeException("空数组,无法建树");
} else {
// 创建优先队列对象
PriorityQueue<TNode> que = new PriorityQueue<TNode>(arr.length,
new MyComparator());
// 将数组中的元素建立结点对象并加入到优先队列中去
for (int i = 0; i < arr.length; i++) {
TNode node = new TNode(arr[i]);
que.add(node);
}
while (que.size() > 1) {
// 将两个结点连成树
TNode ltree = que.poll();
TNode rtree = que.poll();
TNode node = new TNode((Integer) ltree.getObj()
+ (Integer) rtree.getObj());
node.setLeft(ltree);
node.setRight(rtree);
ltree.setParent(node);
rtree.setParent(node);
// 加入子结点
que.add(node);
}
root = que.poll();
}
}
/**
* 打印此树的霍夫曼编码
*
* @param node
* 由指定位置开始做为根结点
*
*/
public void printHCode(TNode node) {
if (node == null) {
throw new RuntimeException("空树,无法编码!");
} else {
TNode current = node;
if (current.getLeft() != null) {
// 向左编码1
current.getLeft().setCode(current.getCode() + '1');
printHCode(current.getLeft());
// 向右编码0
current.getRight().setCode(current.getCode() + '0');
printHCode(current.getRight());
} else {
System.out.println(current.getObj()+"的霍夫曼编码是: \t"+current.getCode());
}
}
}
2.将算术表达式建成树
在这段代码中主要通过将原本的代码转换为逆波兰表达式,以去除括号,然后转换为波兰表达式(波兰表达式将运算符写在前面,操作数写在后面,便于建树),建成树。计算时只需要后序遍历就可以简单的计算这个数学算式。
代码如下:
/**
* 将一个数学算式转化为一个树
*
* @param s
* 此算式的字符串
*/
public void AFtoTree(String s) {
Stack<Character> sta = new Stack<Character>();
sta.push('#');
char[] ch = new char[s.length() + 1];
int j = 0;
// 将中序表达式转化为逆波兰表达式
for (int i = 0; i < s.length(); i++) {
char cha = s.charAt(i);
if (cha != '+' && cha != '-' && cha != '*' && cha != '/'
&& cha != '(' && cha != ')') {
ch[j++] = cha;
} else if (cha == '(') {
sta.push(cha);
} else if (cha == ')') {
char c = sta.pop();
while (c != '(') {
ch[j++] = c;
c = sta.pop();
}
} else {
char c = sta.peek();
while (c == '*' || c == '/') {
ch[j++] = sta.pop();
c = sta.peek();
}
sta.push(cha);
}
}
char c = sta.pop();
while (c != '#') {
ch[j++] = c;
c = sta.pop();
}
// 将逆波兰转化为波兰表达式
char[] temp = new char[j + 1];
for (int i = 0; i < j; i++) {
temp[j - i - 1] = ch[i];
}
temp[j] = '#';
// 由波兰表达式建树
root = creatAFTree(temp);
}
/**
* 将波兰表达式建成一棵树
*
* @param ch
* @param key
* @return
*/
public TNode creatAFTree(char[] ch) {
TNode current = null;
if (ch[key] != '#') {
if (ch[key] == '+' || ch[key] == '-' || ch[key] == '*'
|| ch[key] == '/') {
current = new TNode(ch[key++]);
TNode temp = creatAFTree(ch);
if (temp == null) {
} else {
current.setLeft(temp);
temp.setParent(current);
}
TNode temp2 = creatAFTree(ch);
if (temp2 == null) {
} else {
current.setRight(temp2);
temp2.setParent(current);
}
return current;
} else {
current = new TNode(ch[key++]);
return current;
}
} else {
return null;
}
}
分享到:
相关推荐
递归先序遍历二叉树: 递归中序遍历二叉树: 递归后序遍历二叉树: 非递归先序遍历二叉树: 非递归中序遍历二叉树: 非递归后序遍历二叉树: 非递归中序遍历二叉树(算法2): 层次遍历二叉树: 递归计算单...
C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树...
二叉树是一种特殊的树形数据结构,每个节点最多有两个子节点,通常分为左子节点和右子节点。在C++中,二叉树可以被表示为一个类,包含节点的数据和指向子节点的指针。在给定的文件中,二叉树的节点使用了孩子兄弟...
从给定的文件信息来看,该段代码主要涉及到了数据结构中的两个重要概念:霍夫曼树(Huffman Tree)和二叉搜索树(Binary Search Tree),并使用C++语言进行实现。以下是对这两个知识点的详细解析: ### 霍夫曼树...
"数据结构java树与二叉树PPT课件.pptx" 本资源是关于数据结构中的树和二叉树的PPT课件,共51页。该资源对树和二叉树的定义、基本术语、类型、遍历方法等进行了详细的介绍。 树的定义: 树是由n(n≥0)个有限数据...
java实现二叉树非递归前序中序后序遍历
本资源包含的是用Java编程语言实现的二叉树代码,对于学习Java和数据结构的开发者来说极具价值。 二叉树主要分为几种类型,包括: 1. 完全二叉树:在完全二叉树中,除了最后一层外,每一层都被完全填满,并且所有...
霍夫曼树用的是类模板,还包括一些树的基本操作,遍历,结点数,深度等!对初学者还是很有意义的!!
霍夫曼编码是基于频率的变长编码,通过构建一棵特殊的二叉树——霍夫曼树(又称为最优二叉树或最小带权路径长度树)来实现。在霍夫曼树中,出现频率较高的字符对应较短的编码,而出现频率较低的字符对应较长的编码,...
代码实现: 二叉树的查找、插入、删除和输出根节点到当前节点的路径 二叉树的前序遍历,中序遍历和后续遍历 TreeNode.java --定义树节点 Mytree.java----创建树结构和上述功能函数 TestTree.java --测试上述的功能
### Java二叉树算法实现:节点插入与遍历示例代码 #### 一、核心概念与定义 在深入了解本文档中的代码之前,我们先来回顾一下二叉树的基本概念: - **二叉树**是一种非线性的数据结构,每个节点最多有两个子节点...
霍夫曼树,又称最优二叉树或最小带权路径长度树,是一种特殊的二叉树,主要用于数据编码,包括压缩和解压缩。在文件压缩领域,霍夫曼编码是一种常用的无损数据压缩方法,它利用字符出现频率进行编码,频率高的字符用...
在计算机科学中,二叉树是一种特殊的图结构,每个节点最多有两个子节点,通常分为左子节点和右子节点。在Java中实现二叉树的基本操作是编程学习中的一个重要环节,这包括创建、插入节点、删除节点、遍历以及查找等...
本文将深入探讨霍夫曼编码的概念、工作原理以及如何利用它进行加密和解密。 霍夫曼编码的基本思想是为出现频率高的字符分配较短的编码,而为出现频率低的字符分配较长的编码。这样,常见的字符在数据中占用的空间更...
在Java编程语言中,GUI(图形用户界面)与数据结构如二叉树和平衡树的结合可以帮助我们构建交互式的应用程序。在这个特定的项目中,开发者实现了一个包含两种表示方式(链式和数组形式)的二叉树以及平衡树的模型。...
在本项目中,“基于JAVA开发的二叉树课程设计与实现”主要涵盖了计算机科学中的数据结构和算法领域,特别是关于二叉树的理论知识、Java编程语言的应用以及软件工程的基本实践。二叉树是一种重要的非线性数据结构,...
树的基本运算:创建树;输出树(凹入显示);遍历树(先序、中序、后序、层次);求二叉树的深度;求叶子数;求结点数。
在Java中实现二叉树可视化,开发者通常会利用Java的面向对象特性,定义类来表示节点,并创建一个独立的类来管理树的显示和用户交互。通过这些类,用户可以构建和操纵二叉树,同时在屏幕上看到相应的视觉反馈。这种...
霍夫曼二叉树,又称为最优二叉树或最小带权路径长度树,是一种特殊的二叉树,常用于数据压缩。在数据压缩领域,霍夫曼编码是基于霍夫曼树实现的一种前缀编码方法,它能有效地减少数据的存储空间。霍夫曼编码通过为每...
在IT领域,数据结构是计算机科学的基础,而霍夫曼树和堆排序是两种非常重要的数据结构和算法。本文将详细解析这两个概念及其在C++中的实现。 首先,让我们了解霍夫曼树(Huffman Tree),它是一种特殊的二叉树,也...