【劍指Offer學習】【面試題18 :樹的子結構】
阿新 • • 發佈:2019-01-04
題目:輸入兩棵二叉樹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));
}
}
執行結果
輸入的樹:
輸出結果: