轉載本文章請標明作者和出處
本文出自《Darwin的程序空間》
本文題目和部分解題思路來源自《劍指offer》第二版
題目
請完成一個函數,輸入一顆二叉樹,該函數出處它的鏡像。二叉樹的節點定義如下
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) {
val = x;
}
}
對有些同學來說,鏡像的概念可能比較新,如下,兩個二叉樹就互爲鏡像二叉樹;
解題分析
做這道題,如果想不明白的話,我們可以畫圖看看實例中的第一個二叉樹怎麼可以變成第二個;
我們先試着交換一下根節點8的左右節點,因爲看兩幅圖8節點的兩個子節點6、10是反的;
有點像了,對比一下兩幅圖片,好像就差10、6的子節點是反的了,再交換一下這兩個節點的子節點看一下;
結果即爲答案,那麼我們可以大膽的推測,獲取鏡像二叉樹,就是把二叉樹裏面所有節點的左右節點互換即可;
思想有了,然後就是實現的手段,手段可能有很多,常規的遞歸,你也可以用一個隊列依次交換節點的左右節點;這都不重要了,重要的是你要把它實現出來;
代碼(JAVA實現)
ps:這裏筆者使用的jdk爲1.8版本
測試數據即爲圖示數據;
public class Offer27_MirrorTree {
public static void main(String[] args) {
TreeNode root = new TreeNode(8);
TreeNode t1 = new TreeNode(6);
TreeNode t2 = new TreeNode(10);
TreeNode t3 = new TreeNode(5);
TreeNode t4 = new TreeNode(7);
TreeNode t5 = new TreeNode(9);
TreeNode t6 = new TreeNode(11);
root.left = t1;
root.right = t2;
t1.left = t3;
t1.right = t4;
t2.left = t5;
t2.right = t6;
mirrorTree(root);
System.out.println();
}
public static TreeNode mirrorTree(TreeNode root) {
if (Objects.isNull(root)) {
return null;
}
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
mirrorTree(root.left);
mirrorTree(root.right);
return root;
}
}
代碼的執行流程
我們可以想一下上面的代碼是怎麼執行的?
首先,root節點進入函數,也就是節點8,判斷不爲空,於是交換節點6,節點10兩個節點;
然後用左節點爲參數繼續調用函數,這是的左節點已經是節點10,節點10進入函數不爲空,交換左右節點,節點11和節點9
然後節點11進入函數,交換一下左右節點(其實都爲空,交換了一下空氣),然後把左右空節點都再進入循環一次,但是都被打出;
然後節點9進入循環,和節點11一樣,實際上沒有變化;
然後節點6進入函數,同節點10,交換節點5和節點7,再交換一下並不存在的兩個節點的左右節點,最後完成交換,返回root節點8;
如果我們邏輯沒有問題的話,我們想一下如果在這打印一個輸出,輸出結果會是多少
這裏如果分析沒錯的話,結果會是:
【8、10、11、9、6、7、5】
我們打印一下答案:
最後,隊列實現的代碼也附上;(如果有小夥伴想學習又看不明白,可以聯繫我,我再寫教程)
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode current = queue.poll();
TreeNode temp = current.left;
current.left = current.right;
current.right = temp;
if (current.left != null) queue.add(current.left);
if (current.right != null) queue.add(current.right);
}
return root;
}