劍指offer程式碼解析——面試題19二叉樹的映象
阿新 • • 發佈:2022-05-03
分析:所謂“映象”就是從鏡子裡看到的樣子。我們可以畫一棵二叉樹,然後畫出該二叉樹的映象。畫完圖之後我們會發現,所謂“二叉樹的映象”就是把二叉樹中所有子樹的左孩子和右孩子進行交換。因此需要遍歷二叉樹所有的結點,在遍歷的同時交換非葉子結點的左右子樹。遍歷我們可以使用先序遍歷,首先判斷當前根結點是否為葉子結點,若非葉子結點,則交換左右孩子,然後再分別對左右孩子進行相同的操作。
首先,我們需要構造二叉樹的結點類,一個結點中包含一個數據域data、一個左孩子left、一個右孩子right,程式碼如下:
/** * 二叉樹的結點 */ class BinaryTreeNode<T>{ T data;//結點的資料域 BinaryTreeNode<T> left;//左子樹 BinaryTreeNode<T> right;//右子樹 }
下面開始編寫映象函式:
/** * 二叉樹映象函式 * @param root 輸入二叉樹的根結點 */ public static <T> void binaryTreeMirror(BinaryTreeNode<T> root){ //若二叉樹為空 if(root==null) return; //若二叉樹只有一個結點 if(root.left==null && root.right==null) return; //若二叉樹為有孩子結點,則交換左右子樹 { //交換左右子樹 BinaryTreeNode<T> temp = root.left; root.left = root.right; root.right = temp; } //分別對左右重複上述操作 { if(root.left!=null) binaryTreeMirror(root.left); if(root.right!=null) binaryTreeMirror(root.right); } }
為了能夠對上述演算法進行測試,我編寫了一個二叉樹的中序遍歷函式,我們可以比較二叉樹映象前和映象後的中序遍歷結果來判斷演算法是否正確。二叉樹中序遍歷函式如下:
<span style="white-space:pre"> </span>/** * 二叉樹的中序遍歷 * @param root 輸入的二叉樹的根 */ public static <T> void preOrder(BinaryTreeNode<T> root){ //若當前二叉樹為空 if(root==null) return; //中序遍歷二叉樹 { preOrder(root.left);//中序遍歷左子樹 System.out.print(root.data+",");//訪問根結點 preOrder(root.right);//中序遍歷右子樹 } }
一切準備工作就緒,下面就開始測試我們的演算法吧。
我建立了一棵四個結點的二叉樹,並且所有結點均是左孩子。那麼經過映象後該二叉樹的所有結點應該都是右孩子。並且前後兩棵樹的中序遍歷正好是逆序關係。
public static void main(String[] args){
BinaryTreeNode<Integer> root = new BinaryTreeNode<Integer>();
BinaryTreeNode<Integer> root1 = new BinaryTreeNode<Integer>();
BinaryTreeNode<Integer> root2 = new BinaryTreeNode<Integer>();
BinaryTreeNode<Integer> root3 = new BinaryTreeNode<Integer>();
root.data = 0;
root1.data = 1;
root2.data = 2;
root3.data = 3;
root.left = root1;
root1.left = root2;
root2.left = root3;
System.out.println("映象前:");
preOrder(root);
System.out.println("映象後:");
binaryTreeMirror(root);
preOrder(root);
}
輸出結果為:
映象前:3,2,1,0
映象後:0,1,2,3