Skip to content

Commit 7169623

Browse files
committed
update binary search tree
1 parent 37ea5df commit 7169623

File tree

2 files changed

+81
-7
lines changed

2 files changed

+81
-7
lines changed

go/binarytree/bst.go

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// 图解参考: http://www.cnblogs.com/MrListening/p/5782752.html
12
package binarytree
23

34
type Node struct {
@@ -25,6 +26,19 @@ func (n *Node) Value() int {
2526
return n.value
2627
}
2728

29+
func (n *Node) delete(parent bool) {
30+
if parent && n.parent != nil {
31+
if n.parent.left == n {
32+
n.parent.left = nil
33+
} else {
34+
n.parent.right = nil
35+
}
36+
}
37+
n.left = nil
38+
n.right = nil
39+
n.parent = nil
40+
}
41+
2842
type BSTree struct {
2943
head *Node
3044
size int
@@ -87,23 +101,70 @@ func (bst *BSTree) Find(i int) *Node {
87101
return nil
88102
}
89103

104+
// 分四种情况处理:
105+
// 1. 要删除的节点无左右孩子
106+
// 2. 要删除的节点只有左孩子
107+
// 3. 要删除的节点只有右孩子
108+
// 4. 要删除的节点有左、右孩子
90109
func (bst *BSTree) Delete(i int) bool {
110+
var parent *Node
91111
h := bst.head
92112
n := &Node{value: i}
93113
for h != nil {
94114
switch n.Compare(h) {
95115
case -1:
116+
parent = h
96117
h = h.left
97118
case 1:
119+
parent = h
98120
h = h.right
99121
case 0:
100-
if h.left != nil {
101-
h.parent.left = h.left
122+
isleftleaf := false
123+
if h != bst.head && parent.left == h { // 当前节点不是root节点
124+
isleftleaf = true
102125
}
103-
if h.right != nil {
104-
h.parent.right = h.right
126+
if h.left == nil && h.right == nil {
127+
if h == bst.head {
128+
bst.head = nil
129+
bst.size--
130+
return true
131+
}
132+
h.delete(true)
133+
}
134+
135+
if h.left != nil && h.right == nil {
136+
if h == bst.head {
137+
bst.head = h.left
138+
bst.size--
139+
return true
140+
}
141+
if isleftleaf {
142+
parent.left = h.left
143+
} else {
144+
parent.right = h.left
145+
}
146+
h.delete(false)
147+
}
148+
149+
if h.right != nil && h.left == nil {
150+
if h == bst.head {
151+
bst.head = h.right
152+
bst.size--
153+
return true
154+
}
155+
if isleftleaf {
156+
parent.left = h.right
157+
} else {
158+
parent.right = h.right
159+
}
160+
h.delete(false)
161+
}
162+
163+
if h.left != nil && h.right != nil {
164+
leftmost := findLeftmost(h.right)
165+
h.value, leftmost.value = leftmost.value, h.value
166+
leftmost.delete(true)
105167
}
106-
h = nil
107168
bst.size--
108169
return true
109170
}
@@ -115,6 +176,17 @@ func (bst *BSTree) Size() int {
115176
return bst.size
116177
}
117178

179+
func findLeftmost(n *Node) *Node {
180+
if n == nil {
181+
return nil
182+
}
183+
ret := n
184+
for ret.left != nil {
185+
ret = ret.left
186+
}
187+
return ret
188+
}
189+
118190
func PreOrder(root *Node, ret *[]int) {
119191
if root == nil {
120192
return

go/binarytree/bst_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ func TestBSTree(t *testing.T) {
2828
}
2929

3030
five := bst.Find(5)
31-
if five.Value() != 5 {
31+
if five.Value() != 5 || five.parent.value != 4 ||
32+
five.right.value != 6 || five.left != nil {
3233
t.Errorf("node value should be 5")
3334
return
3435
}
@@ -40,7 +41,8 @@ func TestBSTree(t *testing.T) {
4041
}
4142

4243
four := bst.Find(4)
43-
if four.Value() != 4 {
44+
if four.Value() != 4 || four.right.value != 6 ||
45+
four.left.value != 2 || four.parent.value != 1 {
4446
t.Errorf("node value should be 4")
4547
return
4648
}

0 commit comments

Comments
 (0)