1. 程式人生 > >【劍指Offer學習】【面試題18 :樹的子結構】

【劍指Offer學習】【面試題18 :樹的子結構】

題目:輸入兩棵二叉樹A 和B,判斷B 是不是A 的子結構。

二叉樹結點的定義:

/**
 * 二叉樹的樹結點
 */
 public static class BinaryTreeNode {
    int value;
    BinaryTreeNode left;
    BinaryTreeNode right;
}

解題思路:

要查詢樹A 中是否存在和樹B 結構一樣的子樹,我們可以分成兩步: 第一步在樹A 中找到和B 的根結點的值一樣的結點R, 第二步再判斷樹A 中以R 為根結點的子樹是不是包含和樹B 一樣的結構。

程式碼實現

public class
Test18 {
/** * 二叉樹的樹結點 */ public static class BinaryTreeNode { int value; BinaryTreeNode left; BinaryTreeNode right; } /** * 輸入兩棵二叉樹A和B,判斷B是不是A的子結構。 * 該方法是在A樹中找到一個與B樹的根節點相等的元素的結點, * 從這個相等的結點開始判斷樹B是不是樹A的子結構,如果找到其的一個就返回, * 否則直到所有的結點都找完為止。 * * @param
root1 樹A的根結點 * @param root2 樹B的根結點 * @return true:樹B是樹A的子結構,false:樹B是不樹A的子結構 */
public static boolean hasSubtree(BinaryTreeNode root1, BinaryTreeNode root2) { // 只要兩個物件是同一個就返回true // 【注意此處與書本上的不同,書本上的沒有這一步】 if (root1 == root2) { return true; } // 只要樹B的根結點點為空就返回true
if (root2 == null) { return true; } // 樹B的根結點不為空,如果樹A的根結點為空就返回false if (root1 == null) { return false; } // 記錄匹配結果 boolean result = false; // 如果結點的值相等就,呼叫匹配方法 if (root1.value == root2.value) { result = match(root1, root2); } // 如果匹配就直接返回結果 if (result) { return true; } // 如果不匹配就找樹A的左子結點和右子結點進行判斷 return hasSubtree(root1.left, root2) || hasSubtree(root1.right, root2); } /** * 從樹A根結點root1和樹B根結點root2開始,一個一個元素進行判斷,判斷B是不是A的子結構 * * @param root1 樹A開始匹配的根結點 * @param root2 樹B開始匹配的根結點 * @return 樹B是樹A的子結構,false:樹B是不樹A的子結構 */ public static boolean match(BinaryTreeNode root1, BinaryTreeNode root2) { // 只要兩個物件是同一個就返回true if (root1 == root2) { return true; } // 只要樹B的根結點點為空就返回true if (root2 == null) { return true; } // 樹B的根結點不為空,如果樹A的根結點為空就返回false if (root1 == null) { return false; } // 如果兩個結點的值相等,則分別判斷其左子結點和右子結點 if (root1.value == root2.value) { return match(root1.left, root2.left) && match(root1.right, root2.right); } // 結點值不相等返回false return false; } public static void main(String[] args) { BinaryTreeNode root1 = new BinaryTreeNode(); root1.value = 8; root1.right = new BinaryTreeNode(); root1.right.value = 7; root1.left = new BinaryTreeNode(); root1.left.value = 8; root1.left.left = new BinaryTreeNode(); root1.left.left.value = 9; root1.left.right = new BinaryTreeNode(); root1.left.right.value = 2; root1.left.right.left = new BinaryTreeNode(); root1.left.right.left.left = new BinaryTreeNode(); root1.left.right.left.left.value = 4; root1.left.right.left.right = new BinaryTreeNode(); root1.left.right.left.right.value = 7; BinaryTreeNode root2 = new BinaryTreeNode(); root2.value = 8; root2.left = new BinaryTreeNode(); root2.left.value = 9; root2.right = new BinaryTreeNode(); root2.right.value = 2; System.out.println(hasSubtree(root1, root2)); System.out.println(hasSubtree(root2, root1)); System.out.println(hasSubtree(root1, root1.left)); System.out.println(hasSubtree(root1, null)); System.out.println(hasSubtree(null, root2)); System.out.println(hasSubtree(null, null)); } }

執行結果

輸入的樹:

這裡寫圖片描述

輸出結果:

這裡寫圖片描述