关于二叉树的前序、中序、后序问题
2016-05-03 16:46
253 查看
关于二叉树的前序、中序、后序问题
前序遍历:1. 访问根节点
2. 前序遍历左子树
3. 前序遍历右子树
中序遍历:
1. 中序遍历左子树
2. 访问根节点
3. 中序遍历右子树
后序遍历:
1. 后序遍历左子树
2. 后序遍历右子树
3. 访问根节点
写到这里可能还是有很多人不理解,接下来我写一点程序来帮助大家理解
public class Node{ Node left; Node right; char value; }
这是一个二叉树最基本的结点类,而关于二叉树的遍历其实特别的简单
public static void postTrav(Node root){ //遍历左子树 if(root.left!=null) postTrav(root.left); //遍历右子树 if(root.right!=null) postTrav(root.right); //输出本节点 System.out.println(root.value); }
这便是二叉树的后序遍历,看了后是不是焕然大悟,只要将其中的if语句与输出语句进行调整,就能很快的写出二叉树的前序中序和后序遍历。
在笔试或面试过程中有时会被问到已知树的前序和中序求后序这类的问题。(其实就是我前段时间笔试遇到了~才去认真看了下这些知识),下面对其进行介绍说明,最主要的思想是递归。
1. 已知前序和中序,求后序。
上面的程序中写了遍历树的方法,可以很快求出二叉树的前序中序后序,直接用不就好了么?是的!前提是我要首先要知道这棵树是什么样的,因此我们需要通过给出的前序和中序,构造出这个完整的树。怎么构造这棵树呢?下面我们举个例子,假设一棵树
前序遍历: GDAFEMHZ
中序遍历: ADEFGHMZ
第一步,根据前序遍历的特点,我们知道根结点为G
第二步,观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树,G右侧的HMZ必然是root的右子树。
第三步,观察左子树ADEF,左子树的中的根节点必然是大树的root的leftchild。在前序遍历中,大树的root的leftchild位于root之后,所以左子树的根节点为D。
第四步,同样的道理,root的右子树节点HMZ中的根节点也可以通过前序遍历求得。在前序遍历中,一定是先把root和root的所有左子树节点遍历完之后才会遍历右子树,并且遍历的左子树的第一个节点就是左子树的根节点。同理,遍历的右子树的第一个节点就是右子树的根节点。
第五步,观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。
下面用代码实现构树:
private static void buildBinaryTree(String pre, String mid, Node root) { int len=pre.length(); if(len==0)return; int pos=0; //计算出前序第一位,即根结点在中序的第几位 for(int i=0;i<mid.length();i++){ if(mid.charAt(i)==pre.charAt(0)){ pos=i; break; } } //根结点的值即为前序第一位的值 root.value=pre.charAt(0); if(pos!=0){//当前节点的左子树是存在的 Node left=new Node(); root.left=left; //求出左子树的前序和中序 String left_pre=pre.substring(1,pos+1); String left_mid=mid.substring(0,pos); //递归建立左子树 buildBinaryTree(left_pre, left_mid, left); } if(pos!=len-1){//当前节点的右子树是存在的 Node right=new Node(); root.right=right; //求出右子树的前序和中序 String right_pre=pre.substring(pos+1,len); String right_mid=mid.substring(pos+1,len); //递归建立右子树 buildBinaryTree(right_pre, right_mid, right); } }
2. 已知前序和后序,求中序。
此种情况是不可唯一确定解的,只能确定根节点,而对于左右子树的组成不确定。3. 已知中序和后序,求前序。
其过程与已知前序和中序求后序类似,这里不在重复。下面给出完整的java代码:
public class Main{ public static class Node{ Node left; Node right; char elem; } public static void postTrav(Node root){ //遍历左子树 if(root.left!=null) postTrav(root.left); //遍历右子树 if(root.right!=null) postTrav(root.right); //输出本节点 System.out.println(root.elem); } public static void main(String[] args){ String pre="GDAFEMHZ"; String in="ADEFGHMZ"; Node root=new Node(); buildBinaryTree(pre,in,root); postTrav(root); } private static void buildBinaryTree(String pre, String in, Node root) { // TODO Auto-generated method stub int len=pre.length(); if(len==0)return; int pos=0; for(int i=0;i<in.length();i++){ if(in.charAt(i)==pre.charAt(0)){ pos=i; break; } } root.elem=pre.charAt(0); if(pos!=0){//当前节点的左子树是存在的 Node left=new Node(); root.left=left; String left_pre=pre.substring(1,pos+1); String left_in=in.substring(0,pos); buildBinaryTree(left_pre, left_in, left); } if(pos!=len-1){//当前节点的右子树是存在的 Node right=new Node(); root.right=right; //right.elem=pre.charAt(pos+1); String right_pre=pre.substring(pos+1,len); String right_in=in.substring(pos+1,len); buildBinaryTree(right_pre, right_in, right); } } }
相关文章推荐
- 图像处理中,SIFT,FAST,MSER,STAR等特征提取算法的比较与分析(利用openCV实现)
- Java 集合之Collection 接口和遍历方法
- solrStudy-中文分词器
- MATLAB基础
- ScrollView中嵌套GridView,ListView只显示一行的解决办法
- Windows 安装配置 Zabbix Agentd
- Android GridView Item居中(可能是最完美的解决方案)
- Angularjs 基于$timeout延时加载js
- 内存堆和栈的区别
- c#之process类相关整理
- Android 之 OO Principle(面向对象的原则)
- FAST Corner Detection -- Edward Rosten
- Linux 小工具学习之(1)——Wget十例[翻译]
- A server with the specified hostname could not be found.
- 利用nginx实现文档服务器限速
- pluck()取表中一列中所有值组成数组
- hdu 1558 Segment set【并查集+计算几何】
- 使用框架的意义与spring的主要内容
- [从头学声学] 第203节 复合的声波(2)
- UGUI中背景分辨率适应