咱們知道遍歷一顆二叉樹通常有三種方式:先序、中序、後序。並且每一顆二叉樹的三種遍歷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; } }輸出結果: