-
Notifications
You must be signed in to change notification settings - Fork 0
/
subtree_of_another_tree.rs
117 lines (103 loc) · 3.53 KB
/
subtree_of_another_tree.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#![allow(dead_code)]
use std::cell::RefCell;
use std::rc::Rc;
type Tree = Option<Rc<RefCell<TreeNode>>>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Tree,
pub right: Tree,
}
impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
pub fn add_left(&mut self, val: i32) {
let left_node = Some(Rc::new(RefCell::new(TreeNode::new(val))));
self.left = left_node;
}
pub fn add_right(&mut self, val: i32) {
let right_node = Some(Rc::new(RefCell::new(TreeNode::new(val))));
self.right = right_node;
}
}
pub fn is_subtree(root: Tree, sub_root: Tree) -> bool {
match (root, sub_root) {
(None, _) => false,
(Some(root), Some(sub_root)) => {
is_same_tree(Some(root.clone()), Some(sub_root.clone()))
|| is_subtree(root.borrow().left.clone(), Some(sub_root.clone()))
|| is_subtree(root.borrow().right.clone(), Some(sub_root.clone()))
}
_ => false,
}
}
/*
Algorithm - Recursion
- If root is None, then return false
- If root is not None, then check if root and sub_root are same
- If they are same, then return true
- If they are not same, then check if left subtree of root and sub_root are same
- If they are same, then return true
- If they are not same, then check if right subtree of root and sub_root are same
- If they are same, then return true
- If they are not same, then return false
*/
fn is_same_tree(root: Tree, sub_root: Tree) -> bool {
match (root, sub_root) {
(None, None) => true,
(Some(root), Some(sub_root)) => {
root.borrow().val == sub_root.borrow().val
&& is_same_tree(root.borrow().left.clone(), sub_root.borrow().left.clone())
&& is_same_tree(root.borrow().right.clone(), sub_root.borrow().right.clone())
}
_ => false,
}
}
/*
Algorithm - Recursion
- If both trees are empty then they are same
- If both trees are non-empty
- Check if current data of both trees are same
- Recursively check if left subtree of both trees are same
- Recursively check if right subtree of both trees are same
- If one of them is empty and other is not, then they are not same
*/
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_is_not_subtree() {
let root = Some(Rc::new(RefCell::new(TreeNode::new(3))));
let sub_root = Some(Rc::new(RefCell::new(TreeNode::new(4))));
assert_eq!(is_subtree(root, sub_root), false);
}
#[test]
fn test_is_subtree() {
let root = Some(Rc::new(RefCell::new(TreeNode::new(3))));
let sub_root = Some(Rc::new(RefCell::new(TreeNode::new(3))));
assert_eq!(is_subtree(root, sub_root), true);
}
#[test]
fn test_is_subtree_large() {
let root = Some(Rc::new(RefCell::new(TreeNode::new(3))));
root.as_ref().unwrap().borrow_mut().add_left(4);
root.as_ref().unwrap().borrow_mut().add_right(5);
root.as_ref()
.unwrap()
.borrow_mut()
.right
.as_ref()
.unwrap()
.borrow_mut()
.add_left(1);
let sub_root = Some(Rc::new(RefCell::new(TreeNode::new(5))));
sub_root.as_ref().unwrap().borrow_mut().add_left(1);
assert_eq!(is_subtree(root, sub_root), true);
}
}