一、中序线索化

二叉树节点定义:

class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
int isleftChild = 1;//0:线索 1:左孩子
int isrightChild = 1; public TreeNode(int val) {
this.val = val;
}
}

在中序遍历的过程中完成线索化

   //preNode始终指向中序序列中前一个访问的节点
private static TreeNode preNode = null;//只能用全局变量的形式来记录。 //curNode始终指向中序序列中当前访问的节点
public static TreeNode inIOrderThread(TreeNode curNode) {
if (curNode == null)
return null; //线索化左子树
InClueTree(curNode.left); //线索化当前节点
if (curNode.left == null) {
curNode.isleftChild = 0;
curNode.left = preNode;
}
if (preNode != null && preNode.right == null) {
preNode.isrightChild = 0;
preNode.right = curNode;
}
preNode = curNode;// //线索化右子树
InClueTree(curNode.right); return curNode;
}

遍历中序线索二叉树

public static void inOrderThreadTravel(TreeNode root) {
while (root != null) {
System.out.print(root.val + " ");
//存在线索,root的直接后继就是root.rigth;
if (root.isrightChild == 0) {
root = root.right;
}
//不存在线索的时候一定存在孩子节点,则root的直接后继就是其右子树的中序第一个元素。
else {
root = root.right;
while (root.left != null && root.isleftChild == 1) {
root = root.left;
}
}
}
}

二、表达式求值

有两个表达式

  (4 + (13 / 5)) = 6        (a)

  ((2 + 1) * 3) = 9    (b)

对应的两个表达式树(a)(b)

特点:数字都在叶子节点,运算符都在根节点。

    +                                   *
/ \ / \
4 / + 3
/ \ / \
13 5 2 1   (a)                    (b)

来看一下表达式树的前中后三种顺序遍历结果;

中序:

  4 + 13 / 5  ---  (a)

  2 + 1 * 3    ---  (b)

可以看出,表达式树的中序遍历结果就是正常书写顺序,也是计算机可以直接求解的方式。

后序:

  4 13 5 / +  ---  (a)

  2 1 + 3 *    ---  (b)

此时遍历结果非书写顺序计算机也不能直接求解,非要按照这个顺序用计算机求解,怎么办?

解决方案:栈

  按照遍历顺序对元素如下的操作:

    1、如果元素是数字,入栈

    2、如果元素是操作符不入栈,反而弹栈两个元素a,b;将a作为运算符的左操作数,b作为右操作数计算得到结果c;将结果c入栈。

    3、重复上述操作,直到没有元素时,此时栈中一定只有一个元素,将其返回。

前序:

  + 4 / 13 5  ---  (a)

  * + 2 / 3    ---   (b)

此时遍历结果非书写顺序计算机也不能直接求解,非要按照这个顺序用计算机求解,怎么办?

解决方案:栈

  与后序列操作类似,只不过按照遍历顺序的逆序,为什么是这样呢?

   因为:栈的特点可以暂存之前遇到的信息,在后续操作中可以从栈中取出之前保存的信息;

      四则运算符都是二元运算符,因此一次计算的顺利完成需要3个信息,两个数字,一个运算符号;

        因此遇到数字时候压栈,遇到操作符时候不压栈,然而弹出两个元素进行计算,这是合理的

      而观察表达式树我们发现,叶子节点全都是数字,跟节点全都是操作符号,在进一步可以这么想,父节点都是操作符,孩子节点都是数字(当然直观来看不是这样的,如表达式树(a)中根节点“+”的右孩子明明是“/”;其实在根节点“+”真正计算的时候,13 和 5的父节点“/”早就是新的数字了);结合树的遍历特点,要么遍历完孩子节点才遍历根节点(后序),要么遍历完孩子节点才遍历根节点(前序),总之,孩子节点(数字)总在父节点(符号)的一侧。不管是先序还是后序,我们都统一为先处理孩子节点,再处理父节点,后序顺序中,孩子节点刚好在父节点之前,因此不做顺序调整,而先序遍历的时候,孩子节点均在父节点之后,因此需要逆序调整。

import java.util.Stack;

public class Solution {
public int evalRPN(String[] tokens) {
int res = 0;
if (tokens == null || tokens.length == 0)
return res;
int len = tokens.length;
Stack<Integer> stack = new Stack();
int i = 0;
for (; i < len; i++) {
if (isNum(tokens[i]))
stack.push(Integer.parseInt(tokens[i]));
else {
int a = stack.pop();
int b = stack.pop();
//除法有顺序要求哦
stack.push(operator(b, a, tokens[i]));
}
}
if (i == len)
return stack.pop();
return res;
} private boolean isNum(String str) {
boolean b = false;
try {
Integer.parseInt(str);
b = true;
} catch (Exception e) {
}
return b;
} private int operator(int a, int b, String s) {
int res = 0;
switch (s) {
case "+": {
res = a + b;
break;
}
case "-": {
res = a - b;
break;
}
case "*": {
res = a * b;
break;
}
case "/": {
res = a / b;
break;
}
}
return res;
}
}

     

binary tree的更多相关文章

  1. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  2. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

  3. Leetcode, construct binary tree from inorder and post order traversal

    Sept. 13, 2015 Spent more than a few hours to work on the leetcode problem, and my favorite blogs ab ...

  4. [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  5. [LeetCode] Verify Preorder Serialization of a Binary Tree 验证二叉树的先序序列化

    One way to serialize a binary tree is to use pre-oder traversal. When we encounter a non-null node, ...

  6. [LeetCode] Binary Tree Vertical Order Traversal 二叉树的竖直遍历

    Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bott ...

  7. [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

  8. [LeetCode] Serialize and Deserialize Binary Tree 二叉树的序列化和去序列化

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  9. [LeetCode] Binary Tree Paths 二叉树路径

    Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...

  10. [LeetCode] Lowest Common Ancestor of a Binary Tree 二叉树的最小共同父节点

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

随机推荐

  1. Artix-7 50T FPGA试用笔记之Create a simple MicroBlaze System

    前言:之前笔者的试用博文提到安富利这块板子非常适合MicroBlaze开发,同时网上关于MicroBlaze的资料非常少(或含糊不清),没有一篇能完整介绍VIVADO SDK的设计流程,所以笔者带来这 ...

  2. 身份证&银行卡识别方案

    一.  调用第三方服务 腾讯云OCR识别: 实现方法:Post图片 URL到腾讯云服务器.Post图片文件 到腾讯云服务器 b.    报价: 月接口调用总量 0<调用量≤1000 1000&l ...

  3. java基础第5天

    数组概述 数组是储存多个变量(元素)的东西(容器} 这多个变量的数据类型要一致 概念:数组是存储同一种数据类型多个元素的集合.也就是一个容器,这个容器有个名字,就是数组名. 数组就是在内存中开辟出一段 ...

  4. linux提权辅助工具(三):privchecker.py

    来自:https://www.securitysift.com/download/linuxprivchecker.py #!/usr/env python ##################### ...

  5. SQL优化(3):使用explain了解SQL性能-part2

    接上文,上文对type列用实例做了说明,本文对Extra列进行一些说明. Extra列 Using filesort 前文说,需要对所有的查询结果进行一次排序,例如当使用order by时.但是若查询 ...

  6. 第三方插件Vue-Lazyload

    使图片懒加载

  7. minio 集群搭建

      具体实际的取舍可以参考官方文档,我使用的是4 node 4 driver 模式 环境机器说明 192.168.31.2 192.168.31.3 192.168.31.4 192.168.31.5 ...

  8. Android开发入门

    教我徒弟Android开发入门(一) 教我徒弟Android开发入门(二) 教我徒弟Android开发入门(三) 出处:http://www.cnblogs.com/kexing/tag/Androi ...

  9. 系列文章--oracle简单入门教程

    oracle入门很简单:八.oracle数据表 1.创建oracle数据表创建oracle数据表的语法如下: create table命令用于创建一个oracle数据表:括号内列出了数据表应当包含的列 ...

  10. Genymotion使用分析

    1.从官网下载Genymotion Genymotion官方下载地址:https://www.genymotion.com/#!/download 没有注册,先进行注册 公司规模选择个人 2.Andr ...