1. 程式人生 > >關於Leetcode中Same Tree一題的理解

關於Leetcode中Same Tree一題的理解

題目如下:

Given two binary trees, write a function to check if they are equal or not.

Two binary trees are considered equal if they are structurally identical and the nodes have the same value.

下面附有一個TreeNode的資料結構:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

比較正經的解決方案如下:

public class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p == null && q == null)return true;
        if(p == null || q == null)return false;
        return (p.val==q.val) && isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }
}

    如果非要說有什麼啟示的話,就是在需要同時根據一個節點的左兒子節點和右兒子節點及自身屬性獲得一個bool值的時候,用“與”操作將這些結果聯絡在一起。

    但是這不是我要說的重點,重點出現在我非常naive的時候寫出的一段程式碼,如下所示:

public class Main {

    public static void main(String[] args) {
        Solution sol = new Solution();
        TreeNode node1 = new TreeNode(0);
        node1.left = new TreeNode(-5);
        TreeNode node2 = new TreeNode(0);
        node2.left = new TreeNode(-8);

        if (sol.isSameTree(node1, node2)) {
            System.out.print("yes");
        }else{
            System.out.print("No");
        }


    }

    public static class Solution {
        public boolean isSameTree(TreeNode p, TreeNode q) {
            if(p == null && q == null){
                return true;
            }else if(p !=null && q!=null){
                if (p.val == q.val){
                    if ((p.left!=null && q.left==null) || (p.left==null && q.left!=null) || (p.right==null && q.right!=null) || (p.right!=null && q.right==null)){
                        return false;
                    }else if(p.left!=null){
                        isSameTree(p.left,q.left);
                    }else if(p.right!=null){
                        isSameTree(p.right,q.right);
                    }
                }else{
                    System.out.println("777");
                    return false;
                }
            }else{
                return false;
            }
            System.out.println("888");
            return true;
        }
    }

      public static class TreeNode {
          int val;
          TreeNode left;
          TreeNode right;
          TreeNode(int x) { val = x; }
     }

}
執行結果如下圖所示:



    你會發現這個結果是有些詭異的,程式輸出777就代表已經返回了false值,那為什麼還會繼續執行輸出888這條訊息呢?程式不是已經返回了嗎?

    產生這種現象的原因在與對return的理解存在偏差。return的含義就是“結束當前這個函式”,那到底是跳出這一層遞迴還是跳出整個遞迴是由我程式的寫法決定的。程式裡這種寫法只是跳出該層的遞歸併不是跳出整個遞迴,在777輸出後,執行return false操作只是會使下面這句程式碼:

isSameTree(p.left,q.left);
    變成false值,但是在上層遞迴中,這裡並沒有直接進行return返回,所以程式還需要向後繼續進行,通過一系列判斷之後,程式輸出了888,然後返回了true值,所以最後得到的結果就是true而不是我YY的false。

    所以,在遇到二叉樹的一些判斷和遞迴時,儘量不要步步深入,否則會陷入if判斷語句的汪洋大海。