在一棵二叉樹總,前序遍歷結果為:ABDGCEFH,中序遍歷結果為:DGBAECHF,求后序遍歷結果。
我們知道:
前序遍歷方式為:根節點->左子樹->右子樹
中序遍歷方式為:左子樹->根節點->右子樹
后序遍歷方式為:左子樹->右子樹->根節點
從這里可以看出,前序遍歷的第一個值就是根節點,然后再中序遍歷中找到這個值,那么這個值的左邊部分即為當前二叉樹的左子樹部分前序遍歷結果,這個值的右邊部分即為當前二叉樹的右子樹部分前序遍歷結果。因此,通過這個分析,可以恢復這棵二叉樹,得到這樣的一段偽碼:
節點 getRoot(前序,中序)
c=前序第一個字符
pos=c在中序中的位置
len1=中序pos左半部分長度
len2=中序pos右半部分長度
新建節點r,令r的元素等於c
r的左兒子=getRoot(前序位置1開始的len1長度部分,中序pos位置的左半部分)
r的右兒子=getRoot(前序位置len1開始右半部分,中序pos位置的右半部分)
return r
如圖1示:
圖1
輸入前序ABDGCEFH,中序DGBAECHF,可以得出
A為該二叉樹的根節點
1: BDG為該二叉樹左子樹的前序
2: DGB為該二叉樹左子樹的中序
根據1和2可以構建一棵左子樹
3: CEFH為該二叉樹右子樹的前序
4: ECHF為該二叉樹右子樹的中序
根據3和4可以構建一個右子樹
執行至該步驟的時候就得到了該二叉樹的雲結構,如圖2所示,A為根節點,BDG在它的左子樹上,CEFG在它的右子樹上。
如此遞歸即可以構建一棵完整的二叉樹
java代碼
class DataNode{ int data; DataNode leftChild = null; DataNode rightChild = null; } public class NodeTree { DataNode rootNode; DataNode tempNode; //int index_root; DataNode left_childDataNode; DataNode right_childDataNode; public DataNode initRootNode(int[] preArray){ rootNode = new DataNode(); rootNode.data = preArray[0]; return rootNode; } public void BuildTree(int[] preArray,int[] midArray,DataNode rootNode){ int index_root = getIndex(midArray, rootNode.data); int lengthOfRightTree = preArray.length - index_root -1; int[] preArray_left; int[] preArray_right; int[] midArray_left; int[] midArray_right; if (index_root>0) { left_childDataNode = new DataNode(); if (index_root==1) { left_childDataNode.data = midArray[0]; rootNode.leftChild = left_childDataNode; }else { preArray_left = new int[index_root]; midArray_left = new int[index_root]; System.arraycopy(preArray, 1, preArray_left, 0, index_root); System.arraycopy(midArray, 0, midArray_left, 0, index_root); left_childDataNode.data = preArray_left[0]; rootNode.leftChild = left_childDataNode; BuildTree(preArray_left, midArray_left, left_childDataNode); } } if (lengthOfRightTree>0) { right_childDataNode = new DataNode(); if (lengthOfRightTree==1) { right_childDataNode.data = midArray[index_root+1]; rootNode.rightChild = right_childDataNode; return; }else { preArray_right = new int[lengthOfRightTree]; midArray_right = new int[lengthOfRightTree]; System.arraycopy(preArray, index_root+1, preArray_right, 0,lengthOfRightTree); System.arraycopy(midArray, index_root+1, midArray_right, 0, lengthOfRightTree); right_childDataNode.data = preArray_right[0]; rootNode.rightChild = right_childDataNode; BuildTree(preArray_right, midArray_right,right_childDataNode); } } } public int getIndex(int[] array,int temp){ int index = -1; for (int i = 0; i < array.length; i++) { if (array[i]==temp) { index = i; return index; } } return index; } //后序遍歷 public void postOrderTraverse(DataNode node){ if (node==null) { return; } postOrderTraverse(node.leftChild); postOrderTraverse(node.rightChild); System.out.print(node.data); } //前序遍歷 public void preOrderTraverse(DataNode node){ if (node==null) { return; } System.out.print(node.data); preOrderTraverse(node.leftChild); preOrderTraverse(node.rightChild); } //中序遍歷 public void inOrderTraverse(DataNode node){ if (node==null) { return; } inOrderTraverse(node.leftChild); System.out.print(node.data); inOrderTraverse(node.rightChild); } public static void main(String args[]){ int[] preArray = {1,2,3}; int[] midArray = {1,2,3}; NodeTree tree = new NodeTree(); DataNode headNode = tree.initRootNode(preArray); tree.BuildTree(preArray, midArray, headNode); tree.postOrderTraverse(headNode); } }