java自定义二叉树续:霍夫曼树和将数学算式建树

主要使用自己上一篇文章中的自定义二叉树类实现了霍夫曼树,霍夫曼编码和讲一个数学算式建成树。
1.霍夫曼树和霍夫曼编码
霍夫曼树即最优二叉树,因为它每个叶子结点到根结点的距离与叶子结点的权值有关,往往此权值越大,它的路径越短,即带权路径长度要保持最小,所以叫它最优二叉树。
[quote]   (1)设给定的一组权值为{W1,W2,W3,……Wn},据此生成森林F={T1,T2,T3,……Tn},F 中的每棵二叉树只有一个带权为Wi的根节点(i=1,2,……n)。
算法思想为:
  (2)在F中选取两棵根节点的权值最小和次小的二叉树作为左右构造一棵新的二叉树,新二叉树根节点的权值为其左、右子树根节点的权值之和。
  (3)在F中删除这两棵最小和次小的二叉树,同时将新生成的二叉树并入森林中。
  (4)重复(2)(3)过程直到F中只有一棵二叉树为止。[/quote]
以下为代码:
结点类的补充
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;
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
程序 = 数据结构 + 算法  程序是为了解决实际问题而存在的。然而为了解决问题,必定会使用到某些数据结构以及设计一个解决这种数据结构的算法。如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功。编程实战算法,不是念PPT,我们讲的就是实战与代码实现与企业应用。程序 = 数据结构 + 算法                ——图灵奖得主,计算机科学家N.Wirth(沃斯)作为程序员,我们做机器学习也好,做python开发也好,java开发也好。有一种对所有程序员无一例外的刚需 —— 算法与数据结构日常增删改查 + 粘贴复制 + 搜索引擎可以实现很多东西。同样,这样也是没有任何竞争力的。我们只可以粘贴复制相似度极高的功能,稍复杂的逻辑没有任何办法。语言有很多,开发框架更是日新月异3个月不学就落后我们可以学习很多语言,很多框架,但招聘不会考你用5种语言10种框架实现同一个功能。真正让程序员有区分度,企业招聘万年不变的重点 —— 算法与数据结构。算法代表程序员水平的珠穆朗玛。 本视频由微软全球最有价值专家尹成录制,拒绝念PPT,代码实战数据结构与算法导论。除了传统数据结构算法,加入高并发线程安全数据结构,分布式负载均衡算法,分布式哈希表,分布式排序等等现代算法。  算法,晦涩难懂,却又是IT领域受重视的素养之一。可以说,算法能力往往决定了一个程序员能够走多远。因此,BAT/FLAG等国内外各大名企非常喜欢在面试环节考核求职者的算法编程,这也成为了无数准程序员们过不去的一道“坎”。如何入门并成为一名出色的算法工程师?但无论半路出家还是科班出身,除学生时代搞算法竞赛的同学外真正用心学习过算法与数据结构太少太少。对于后期想要学习算法与数据结构却不得不面对以下问题:没有自己的知识框架,无法关联知识点,学习效率低有疑问而无人解答,有问题无法理解全靠猜测,一个问题卡好几天市面上资料题解质量参差不齐,正确性未可知Google算法-工程师尹成大哥学习算法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值