Java由先序序列和中序序列还原二叉树
还原本来的二叉树并不是一个非常简单的事,虽然思想比较简单,但过程却是比较繁琐。下面我拿先序序列和中序序列来讲一下原理吧。
从先序序列中我们一下子就可以得到二叉树的根节点是第一个元素,然后再中序序列中我们也可以找到这个元素(假设二叉树中所有的元素的值不相同)这样我们就可以把中序序列分成两部分,前部分和先序序列可求得左子树,后部分与先序序列可求得右子树。下面以左部分为例,在除去根节点的前序序列中的第二个元素,就是我们左子树的的第一个节点,然后继续在中序序列的前部分中找到相同的元素,再次对中序序列进行分割。····最后我们就可以得到恢复的二叉树了。
纯文字的讲述不太容易理解,下面我拿个具体的例子来分析吧。
比如
int[] preOrder = {7,10,4,3,1,2,8,11}; //前序序列
int[] inOrder = {4,10,3,1,7,11,8,2}; //中序序列
我们很容易在前序序列中得知7是根节点,接下来我们在中序序列中找到7所在的位置,那么此时4,10,3,1便是左子树对应的所有的节点。11,8,2是右子树所对应的所有的节点。
然后我们在前序序列中找到除根节点以外的第一个节点,那就是10,所以这就是左子树的第一个节点。然后我们在中序序列中找到10在第二个位置上,而10的左边有一个元素4,右边有3,1两个节点。这就说明4是节点10的左孩子节点,3,1为节点10的右子树上面的节点,然后再前序序列中我们便可以看出3是10的左孩子节点,而3的左边没有元素,说明3美誉哦左孩子节点,3的右边有一个元素1,说明3只有右孩子节点。至此,你是不是也掌握了恢复二叉树的方法了呢?
原理其实并不难理解,但是代码却不是特别好写。所以我拷贝了其他人做好的一份代码,大家一起欣赏一下吧。
package MyBinaryTree;
public class CreateBianryTreeByString {
/**
* Build Binary Tree from PreOrder and InOrder
* _______7______
/ \
__10__ ___2
/ \ /
4 3 _8
\ /
1 11
*/
public static void main(String[] args) {
CreateBianryTreeByString build=new CreateBianryTreeByString();
int[] preOrder = {7,10,4,3,1,2,8,11};
int[] inOrder = {4,10,3,1,7,11,8,2};
Node root=build.buildTreePreOrderInOrder(preOrder,0,preOrder.length-1,inOrder,0,preOrder.length-1);
build.preOrder(root);
System.out.println();
build.inOrder(root);
}
public Node buildTreePreOrderInOrder(int[] preOrder,int begin1,int end1,int[] inOrder,int begin2,int end2){
if(begin1>end1||begin2>end2){
return null;
}
int rootData=preOrder[begin1];
Node head=new Node(rootData);
int divider=findIndexInArray(inOrder,rootData,begin2,end2);
int offSet=divider-begin2-1;
Node left=buildTreePreOrderInOrder(preOrder,begin1+1,begin1+1+offSet,inOrder,begin2,begin2+offSet);
Node right=buildTreePreOrderInOrder(preOrder,begin1+offSet+2,end1,inOrder,divider+1,end2);
head.left=left;
head.right=right;
return head;
}
public int findIndexInArray(int[] a,int x,int begin,int end){
for(int i=begin;i<=end;i++){
if(a[i]==x)return i;
}
return -1;
}
public void preOrder(Node n){
if(n!=null){
System.out.print(n.val+",");
preOrder(n.left);
preOrder(n.right);
}
}
public void inOrder(Node n){
if(n!=null){
inOrder(n.left);
System.out.print(n.val+",");
inOrder(n.right);
}
}
class Node{
Node left;
Node right;
int val;
public Node(int val){
this.val=val;
}
public Node getLeft(){
return left;
}
public Node getRight(){
return right;
}
public int getVal(){
return val;
}
}
}
测试结果:
7,10,4,3,1,2,8,11,//前序序列
4,10,3,1,7,11,8,2,//中序序列
Java由先序序列和中序序列还原二叉树的更多相关文章
- hdu1710-Binary Tree Traversals (由二叉树的先序序列和中序序列求后序序列)
http://acm.hdu.edu.cn/showproblem.php?pid=1710 Binary Tree Traversals Time Limit: 1000/1000 MS (Java ...
- 48. leetcode 105题 由树的前序序列和中序序列构建树结构
leetcode 105题,由树的前序序列和中序序列构建树结构.详细解答参考<剑指offer>page56. 先序遍历结果的第一个节点为根节点,在中序遍历结果中找到根节点的位置.然后就可以 ...
- 已知前序(后序)遍历序列和中序遍历序列构建二叉树(Leetcode相关题目)
1.文字描述: 已知一颗二叉树的前序(后序)遍历序列和中序遍历序列,如何构建这棵二叉树? 以前序为例子: 前序遍历序列:ABCDEF 中序遍历序列:CBDAEF 前序遍历先访问根节点,因此前序遍历序列 ...
- L2-006 树的遍历 (25 分) (根据后序遍历与中序遍历建二叉树)
题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456 L2-006 树的遍历 (25 分 ...
- 玩透二叉树(Binary-Tree)及前序(先序)、中序、后序【递归和非递归】遍历
基础预热: 结点的度(Degree):结点的子树个数:树的度:树的所有结点中最大的度数:叶结点(Leaf):度为0的结点:父结点(Parent):有子树的结点是其子树的根节点的父结点:子结点/孩子结点 ...
- python数据结构之树和二叉树(先序遍历、中序遍历和后序遍历)
python数据结构之树和二叉树(先序遍历.中序遍历和后序遍历) 树 树是\(n\)(\(n\ge 0\))个结点的有限集.在任意一棵非空树中,有且只有一个根结点. 二叉树是有限个元素的集合,该集合或 ...
- c/c++ 用前序和中序,或者中序和后序,创建二叉树
c/c++ 用前序和中序,或者中序和后序,创建二叉树 用前序和中序创建二叉树 //用没有结束标记的char*, clr为前序,lcr为中序来创建树 //前序的第一个字符一定是root节点,然后去中序字 ...
- 03-树3. Tree Traversals Again (25)将先序遍历和中序遍历转为后序遍历
03-树3. Tree Traversals Again (25) 题目来源:http://www.patest.cn/contests/mooc-ds/03-%E6%A0%913 An inorde ...
- 小小c#算法题 - 11 - 二叉树的构造及先序遍历、中序遍历、后序遍历
在上一篇文章 小小c#算法题 - 10 - 求树的深度中,用到了树的数据结构,树型结构是一类重要的非线性数据结构,树是以分支关系定义的层次结构,是n(n>=0)个结点的有限集.但在那篇文章中,只 ...
随机推荐
- hash数组快速查找一个字符串中出现最多的字符,并统计出现的次数
如何快速查找一个字符串中出现最多的字符,并统计出现的次数? 可以使用hash数组,也就是关联数组实现快速查找功能. function seek(str) { var hash = []; var ma ...
- Struts中的找不到StringUtils异常
今天在Struts2框架下使用JSON插件时,程序保存找不到类org/apache/commons/lang/xwork/StringUtils,我纳闷了,commons-lang-2.5.jar和c ...
- eclipse中创建完整的maven项目
使用eclipse插件创建一个web project 首先创建一个Maven的Project如下图 我们勾选上Create a simple project (不使用骨架) 这里的Packing 选择 ...
- 48. Rotate Image(中等)
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...
- 异常处理&RandomAccessFile&节奏感
异常处理 异常处理方面的知识,下面是学习中记的笔记: try尝试捕获异常 catch对捕获的异常进行处理 多个catch要注意的问题: 一.顺序问题,先小后大,也就是先子类后父类.因为当异常出现的时候 ...
- Page Object设计模式实践
Page Object模式是使用Selenium的广大同行最为公认的一种设计模式.在设计测试时,把元素和方法按照页面抽象出来,分离成一定的对象,然后再进行组织. Page Object模式,创建一个对 ...
- webpack2 配置 示例
// https://github.com/webpack-contrib/extract-text-webpack-plugin var webpack = require("webpac ...
- 炫酷:一句代码实现标题栏、导航栏滑动隐藏。ByeBurger库的使用和实现
本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发. 其实上周五的时候已经发过一篇文章.基本实现了底部导航栏隐藏的效果.但是使用起来可能不是很实用.因为之前我实现的方式是继承了系统的 ...
- Android中软键盘弹出时底部菜单上移问题
当在Android的layout设计里面如果输入框过多,则在输入弹出软键盘的时候,下面的输入框会有一部分被软件盘挡住,从而不能获取焦点输入. 解决办法: 方法一:在你的activity中的oncrea ...
- 19 Handler 子线程向主线程发送信息
案例一 Message创建三种方法: package com.example.day19_handler_demo1; import android.os.Bundle; import android ...