先序、中序肯定二叉树

       前言

               咱们知道遍历一颗二叉树通常有三种方式:先序、中序、后序。并且每一颗二叉树的三种遍历java

          方式的结果各自都是惟一的。可是有可能一颗二叉树的先序遍历结果和另外一个不一样的二叉树的中node

          序遍历结果是相同的。咱们可以有二叉树求得其三种遍历结果,那么咱们有可能根据三种遍历结果ide

          去肯定一颗二叉树么?post

      二叉树的肯定

               一、三种单独的遍历方式没法肯定二叉树。code

         略微思考一下就能够明白,先序遍历只能肯定其根节点,对于以后的状况是彻底没法肯定的,一样递归

         的对于中序,后序遍历就也会存在这种状况.。证实很差说,咱们直接用一个反例来讲明。element

                假设先序遍历的结果为ABCD。能够看出的是对于其结果会存在不一样的二叉树的先序遍历都为string

         ABCD。所以只是先序遍历是没法肯定一棵二叉树的。
it

                            

                    至于后序和中序的状况就不在反证了。class

               既然单个的遍历情形没法肯定二叉树那么咱们来经过组合看可否肯定一棵二叉树。

                    二、已知先序和中序能够肯定一棵二叉树。

                         ● 若是先序和中序遍历都是空的,这肯定一棵空二叉树。

                         ● 对于有n(n>=2)个结点的状况先序遍历中的第一个结点必然是二叉树的根结点,而后在

               中序遍历中找到根结点,这样就惟一肯定了根结点了。在中序遍历序列中根结点前面的序列就是

               根结点的左子树的中序遍历序列。同理在先序遍历中根结点以后到中序遍历中的根节点的那部分

               序列就是根节点的作子树的先序遍历。这样递归下去就能够肯定惟一肯定左子树。根节点的右子

               树的分析同理。

                   三、中序遍历和后序遍历能够惟一肯定一颗二叉树。

                          具体的分析参见2.

                   四、先序遍历和后序遍历没法肯定一颗二叉树。

                          略微思考一下就明白了,此种状况只能肯定根节点,可是根节点的左子树,右子树序列根

                本没法肯定。

          先序、中序肯定二叉树实现

                  进过上述分析,咱们知道了二叉树的肯定能够经过两种状况来肯定,也就是先序和中序组合,后序

              中序组合。这里咱们对前者的组合方式作一个实现,下面是代码部分。 

package com.kiritor;  public class TestBinaryTree {  	public static void main(String[] args) { 		BinaryTree bt = new BinaryTree(); 		bt.root = BinaryTree.createBT("ABDCEGFHI", "DBAEGCHFI"); 		System.out.println("PreOrder:");// 先序输出 		bt.preOrder(bt.root); 		System.out.println("\n"); 		System.out.println(" Inorder:");// 中序输出 		bt.inOrder(bt.root); 		System.out.println("\n"); 		System.out.println(" PostOrder:");// 后序输出 		bt.postOrder(bt.root);  	}  }  class BinaryTree { 	protected BinaryTreeNode root;  	public BinaryTree() { 		root = null; 	}  	public BinaryTree(char element) { 		root = new BinaryTreeNode(element); 	}  	public BinaryTree(char element, BinaryTree leftTree, BinaryTree rightTree) { 		root = new BinaryTreeNode(element); 		if (leftTree != null) { 			root.left = leftTree.root; 		} 		if (rightTree != null) { 			root.right = rightTree.root; 		} 	}  	public void preOrder(BinaryTreeNode node) { 		if (node != null) { 			System.out.print(node.element); 			preOrder(node.left); 			preOrder(node.right); 		} 	}  	public void inOrder(BinaryTreeNode node) { 		 		if (node != null) { 			inOrder(node.left); 			System.out.print(node.element); 			inOrder(node.right); 		} 	}  	public void postOrder(BinaryTreeNode node) { 	 		if (node != null) { 			postOrder(node.left); 			postOrder(node.right); 			System.out.print(node.element); 		} 	}  	// 利用先序表达式和中序表达式构建一棵字符二叉树 	public static BinaryTreeNode createBT(String pres, String ins) { 		int inpos = 0; 		BinaryTreeNode root; 		String leftPres, leftIns, rightPres, rightIns; 		if (pres.length() == 0 || ins.length() == 0) { 			return null; 		} else { 			root = new BinaryTreeNode(pres.charAt(0));//首先就能够肯定根结点了 			//以后肯定中序遍历中的根结点的位置 			while (((Character) ins.charAt(inpos)) != root.element) 				inpos++;             //递归肯定左结点 			leftPres = pres.substring(1, inpos + 1); 			leftIns = ins.substring(0, inpos); 			root.left = createBT(leftPres, leftIns);             //递归生成右结点 			rightPres = pres.substring(inpos + 1, pres.length()); 			rightIns = ins.substring(inpos + 1, ins.length()); 			root.right = createBT(rightPres, rightIns); 		} 		return root; 	}  }  class BinaryTreeNode {  	protected char element; 	protected BinaryTreeNode left, right;  	BinaryTreeNode(char obj) { 		element = obj; 		left = null; 		right = null; 	} }
           输出结果: