描述
有两个不同大小的二叉树: T1
有上百万的节点; T2
有好几百的节点。请设计一种算法,判定 T2
是否为 T1
的子树。
若 T1 中存在从节点 n 开始的子树与 T2 相同,我们称 T2 是 T1 的子树。也就是说,如果在 T1 节点 n 处将树砍断,砍断的部分将与 T2 完全相同。
样例
下面的例子中 T2 是 T1 的子树:
1 3
/ /
T1 = 2 3 T2 = 4
/
4
下面的例子中 T2 不是 T1 的子树:
1 3 / T1 = 2 3 T2 = 4 / 4
采用递归;
思路
先从根节点开始比较,若根节点相同,判断二叉树是否为等价二叉树;
若等价,则返回true,否则,若T1左子树或右子树不为空,对其左右子节点分别进行递归调用,判断是否存在等价二叉树。
代码
1 <?PHP 2 header("Content-type: text/html; charset=utf-8"); 3 include "show.php";//定义打印show()函数 4 class Node 5 { 6 public $value; 7 public $right; 8 public $left; 9 10 public function __construct($value) 11 { 12 $this->value = $value; 13 } 14 } 15 16 function is_sub_tree($tree, $sub_tree) 17 { 18 if(empty($sub_tree)) 19 { 20 return true; 21 } 22 23 if(empty($tree)) 24 { 25 return false; 26 } 27 28 if($tree->value == $sub_tree->value) 29 { 30 if(is_check($tree, $sub_tree)) 31 { 32 return true; 33 } 34 } 35 36 if(is_sub_tree($tree->left, $sub_tree)) 37 { 38 return true; 39 } 40 41 if(is_sub_tree($tree->right, $sub_tree)) 42 { 43 return true; 44 } 45 46 return false; 47 } 48 49 function is_check($tree, $sub_tree) 50 { 51 if(empty($sub_tree)) 52 { 53 return true; 54 } 55 56 if(empty($tree)) 57 { 58 return false; 59 } 60 61 if($tree->value == $sub_tree->value) 62 { 63 return is_check($tree->left, $tree->left) && is_check($tree->right, $sub_tree->right); 64 } 65 66 return false; 67 } 68 69 $A = new Node(1); 70 $B = new Node(2); 71 $C = new Node(3); 72 $D = new Node(4); 73 $A->left = $B; 74 $A->right = $C; 75 $C->left = $D; 76 77 $E = new Node(3); 78 $F = new Node(4); 79 $E->left = $F; 80 81 show($A); 82 show($E); 83 var_dump(is_sub_tree($A, $E));