-
Notifications
You must be signed in to change notification settings - Fork 1
/
tree.go
174 lines (165 loc) · 3.55 KB
/
tree.go
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package utils
import (
"math"
)
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// we use math.MinInt32 to represents null
func ConstructTree(s []int) *TreeNode {
n := len(s)
if n == 0 {
return nil
}
q := NewQueue()
var i int
root := &TreeNode{Val: s[i]}
q.Enroll(root)
i++
for !q.IsEmpty() && i < n {
node := q.Pull().(*TreeNode)
if s[i] != math.MinInt32 {
node.Left = &TreeNode{Val: s[i]}
q.Enroll(node.Left)
}
i++
if i < n && s[i] != math.MinInt32 {
node.Right = &TreeNode{Val: s[i]}
q.Enroll(node.Right)
}
i++
}
return root
}
func LevelOrderTravesal(root *TreeNode) []int {
var ret []int
if root == nil {
return ret
}
q := NewQueue()
q.Enroll(root)
for !q.IsEmpty() {
v := q.Pull().(*TreeNode)
ret = append(ret, v.Val)
if v.Left != nil {
q.Enroll(v.Left)
}
if v.Right != nil {
q.Enroll(v.Right)
}
}
return ret
}
// InorderTraversal uses Morris Traversal Algorithm
// time complexity is O(n) and space complexity is O(1)
func InorderTraversal(root *TreeNode) []int {
var ret []int
cur := root
for cur != nil {
if cur.Left == nil {
ret = append(ret, cur.Val)
cur = cur.Right
} else {
predecessor := cur.Left
for predecessor.Right != cur && predecessor.Right != nil {
predecessor = predecessor.Right
}
if predecessor.Right == nil {
predecessor.Right = cur
cur = cur.Left
} else {
predecessor.Right = nil
ret = append(ret, cur.Val)
cur = cur.Right
}
}
}
return ret
}
// PreorderTraversal uses Morris Traversal Algorithm
// time complexity is O(n) and space complexity is O(1)
func PreorderTraversal(root *TreeNode) []int {
var ret []int
cur := root
for cur != nil {
if cur.Left == nil {
ret = append(ret, cur.Val)
cur = cur.Right
} else {
predecessor := cur.Left
for predecessor.Right != cur && predecessor.Right != nil {
predecessor = predecessor.Right
}
if predecessor.Right == nil {
predecessor.Right = cur
ret = append(ret, cur.Val)
cur = cur.Left
} else {
predecessor.Right = nil
cur = cur.Right
}
}
}
return ret
}
// PostorderTraversal uses Morris Traversal Algorithm
// time complexity is O(n) and space complexity is O(1)
func PostorderTraversal(root *TreeNode) []int {
var ret []int
dummy := &TreeNode{Left: root}
var predecessor, first, middle, last *TreeNode
cur := dummy
for cur != nil {
if cur.Left == nil {
// ret = append(ret, cur.Val)
cur = cur.Right
} else {
predecessor = cur.Left
for predecessor.Right != cur && predecessor.Right != nil {
predecessor = predecessor.Right
}
if predecessor.Right == nil {
predecessor.Right = cur
// ret = append(ret, cur.Val)
cur = cur.Left
} else {
// predeccessor found second time
// reverse the right references in chain from predecessor to p
first, middle = cur, cur.Left
for middle != cur {
last = middle.Right
middle.Right = first
first = middle
middle = last
}
// visit the nodes from pred to p
// again reverse the right references from pred to p
first, middle = cur, predecessor
for middle != cur {
ret = append(ret, middle.Val)
last = middle.Right
middle.Right = first
first = middle
middle = last
}
predecessor.Right = nil
cur = cur.Right
}
}
}
return ret
}
func IsEqual(l, r *TreeNode) bool {
if (l == nil && r != nil) || (l != nil && r == nil) {
return false
}
if l == nil && r == nil {
return true
}
if l.Val != r.Val {
return false
}
return IsEqual(l.Left, r.Left) && IsEqual(l.Right, r.Right)
}