原來一直以爲二叉樹遍歷沒有什麼難度,直到最近發現沒有搞太清晰。所以我用Java來實現了一下,來捋順思路。
首先創建一個二叉樹:
package com.company;
/**
* Created by wuguangzu on 14-10-4.
*/
public class BinaryTree {
int data;//根節點數據
BinaryTree left;//左子樹
BinaryTree right;//右子樹
//構造函數實例化二叉樹
public BinaryTree(int data) {
this.data = data;
left = null;
right = null;
}
//向二叉樹中插入節點
public void insert(BinaryTree root, int data){
if(data < root.data){//二叉樹的左節點比根節點小
if(root.left == null){
root.left = new BinaryTree(data);//左節點爲空,則生成左節點
}else {
this.insert(root.left, data);//遞歸調用,插入左節點
}
}else {
if(data > root.data){//二叉樹的右節點比根節點大
if(root.right == null){
root.right = new BinaryTree(data);//右節點爲空,則生成右節點
}else {
this.insert(root.right, data);//不爲空則遞歸調用,插入右節點
}
}
}
}
}
然後就可以創建二叉樹實例,並實現二叉樹的先序遍歷、中序遍歷、後序遍歷:
package com.company;
/**
* Created by wuguangzu on 14-10-4.
*/
public class BinaryTreeTraversal {
//先序遍歷(又稱作先根遍歷,下同)
public static void preTraversal(BinaryTree root){
if (root != null){
System.out.print(root.data + "-");
preTraversal(root.left);
preTraversal(root.right);
}
}
//中序遍歷
public static void inOrderTraversal(BinaryTree root){
if (root != null){
inOrderTraversal(root.left);
System.out.print(root.data + "-");
inOrderTraversal(root.right);
}
}
//後序遍歷
public static void postTraversal(BinaryTree root){
if (root != null){
postTraversal(root.left);
postTraversal(root.right);
System.out.print(root.data + "-");
}
}
public static void main(String args[]){
int arr[] = {23,14,54,45,36,7,22,12,79};
BinaryTree root = new BinaryTree(arr[0]);//創建一個二叉樹
for(int i=0; i<arr.length; i++){
root.insert(root, arr[i]);//向二叉樹中插入數據
}
System.out.println("先序遍歷:");
preTraversal(root);
System.out.println();
System.out.println("中序遍歷:");
inOrderTraversal(root);
System.out.println();
System.out.println("後序遍歷:");
postTraversal(root);
}
}
輸出結果:
先序遍歷:
23-14-7-12-22-54-45-36-79-
中序遍歷:
7-12-14-22-23-36-45-54-79-
後序遍歷:
12-7-22-14-36-45-79-54-23-
練習:
1)可以通過其先序遍歷和中序遍歷推導出圖的形狀,用後序遍歷驗證。2)改變數組的輸出順序可以改變圖的形狀,以此練習推導二叉樹圖。
如果搞不定可以參考下面的例子:
在網上找了一個帶有附圖的二叉樹,其圖如下:
數組定義爲:
int arr[] = {12,76,35,22,16,48,90,46,9,40};
輸出結果:
先序遍歷:
12-9-76-35-22-16-48-46-40-90-
中序遍歷:
9-12-16-22-35-40-46-48-76-90-
後序遍歷:
9-16-22-40-46-48-35-90-76-12-
推導:
1)根據先序遍歷確定根節點爲12。
2)那麼中序遍歷中12前面的爲左子樹,後面的爲樹的右子樹。
3)左子樹只有一個葉子節點,根據先序遍歷,先根,後左右,則9爲12的左節點,76爲右節點。
4)左子樹的數據肯定小於根節點,右子樹大於根節點,那麼只有90是76的右節點。
5)看中序遍歷
16-22-35-40-46-48
有可能是全部都是隻有左葉子節點的左子樹,但是先序遍歷中12-9-76-35
說明35是一個有左右子樹的根節點,那麼以此劃分。
遞歸此思路可解決類似問題。