Skip to content

Commit

Permalink
Merge pull request wangzheng0822#155 from scissorsfeet/master
Browse files Browse the repository at this point in the history
BST by golang
  • Loading branch information
wangzheng0822 authored Nov 16, 2018
2 parents 2270bf0 + ccf862c commit 1ac0b0a
Show file tree
Hide file tree
Showing 6 changed files with 474 additions and 0 deletions.
145 changes: 145 additions & 0 deletions go/24_tree/BinarySearchTree.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package _4_tree

type BST struct {
*BinaryTree
//比对函数,0:v==nodeV,正数:v>nodeV,负数:v<nodeV
compareFunc func(v, nodeV interface{}) int
}

func NewBST(rootV interface{}, compareFunc func(v, nodeV interface{}) int) *BST {
if nil == compareFunc {
return nil
}
return &BST{BinaryTree: NewBinaryTree(rootV), compareFunc: compareFunc}
}

func (this *BST) Find(v interface{}) *Node {
p := this.root
for nil != p {
compareResult := this.compareFunc(v, p.data)
if compareResult == 0 {
return p
} else if compareResult > 0 { //v > nodeV
p = p.right
} else { //v < nodeV
p = p.left
}
}
return nil
}

func (this *BST) Insert(v interface{}) bool {
p := this.root
for nil != p {
compareResult := this.compareFunc(v, p.data)
if compareResult == 0 {
return false
} else if compareResult > 0 {
if nil == p.right {
p.right = NewNode(v)
break
}
p = p.right
} else {
if nil == p.left {
p.left = NewNode(v)
break
}
p = p.left
}
}
return true
}

func (this *BST) Delete(v interface{}) bool {
var pp *Node = nil
p := this.root
deleteLeft := false
for nil != p {
compareResult := this.compareFunc(v, p.data)
if compareResult > 0 {
pp = p
p = p.right
deleteLeft = false
} else if compareResult < 0 {
pp = p
p = p.left
deleteLeft = true
} else {
break
}
}

if nil == p { //需要删除的节点不存在
return false
} else if nil == p.left && nil == p.right { //删除的是一个叶子节点
if nil != pp {
if deleteLeft {
pp.left = nil
} else {
pp.right = nil
}
} else { //根节点
this.root = nil
}
} else if nil != p.right { //删除的是一个有右孩子,不一定有左孩子的节点
//找到p节点右孩子的最小节点
pq := p
q := p.right //向右走一步
fromRight := true
for nil != q.left { //向左走到底
pq = q
q = q.left
fromRight = false
}
if fromRight {
pq.right = nil
} else {
pq.left = nil
}
q.left = p.left
q.right = p.right
if nil == pp { //根节点被删除
this.root = q
} else {
if deleteLeft {
pq.left = q
} else {
pq.right = q
}
}
} else { //删除的是一个只有左孩子的节点
if nil != pp {
if deleteLeft {
pp.left = p.left
} else {
pp.right = p.left
}
} else {
if deleteLeft {
this.root = p.left
} else {
this.root = p.left
}
}
}

return true

}

func (this *BST) Min() *Node {
p := this.root
for nil != p.left {
p = p.left
}
return p
}

func (this *BST) Max() *Node {
p := this.root
for nil != p.right {
p = p.right
}
return p
}
145 changes: 145 additions & 0 deletions go/24_tree/BinarySearchTree_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package _4_tree

import "testing"

var compareFunc = func(v, nodeV interface{}) int {
vInt := v.(int)
nodeVInt := nodeV.(int)

if vInt > nodeVInt {
return 1
} else if vInt < nodeVInt {
return -1
}
return 0
}

func TestBST_Find(t *testing.T) {
bst := NewBST(1, compareFunc)

bst.Insert(3)
bst.Insert(1)
bst.Insert(2)
bst.Insert(7)
bst.Insert(5)

t.Log(bst.Find(2))
}

func TestBST_Insert(t *testing.T) {
bst := NewBST(1, compareFunc)

bst.Insert(3)
bst.Insert(1)
bst.Insert(2)
bst.Insert(7)
bst.Insert(5)

bst.InOrderTraverse()
}

func TestBST_Min(t *testing.T) {
bst := NewBST(1, compareFunc)

bst.Insert(3)
bst.Insert(1)
bst.Insert(2)
bst.Insert(7)
bst.Insert(5)

t.Log(bst.Min())
}

func TestBST_Max(t *testing.T) {
bst := NewBST(1, compareFunc)

bst.Insert(3)
bst.Insert(1)
bst.Insert(2)
bst.Insert(7)
bst.Insert(5)

t.Log(bst.Max())
}

func TestBST_DeleteA(t *testing.T) {
bst := NewBST(1, compareFunc)

bst.Insert(3)
bst.Insert(2)
bst.Insert(7)
bst.Insert(5)

t.Log(bst.Delete(7))

bst.InOrderTraverse()
}

func TestBST_DeleteB(t *testing.T) {
bst := NewBST(1, compareFunc)

t.Log(bst.Delete(1))
t.Log(bst.root)

bst.InOrderTraverse()
}

func TestBST_DeleteC(t *testing.T) {
bst := NewBST(1, compareFunc)

bst.Insert(3)
bst.Insert(2)
bst.Insert(7)
bst.Insert(5)

t.Log(bst.Delete(1))

bst.InOrderTraverse()
}

func TestBST_DeleteD(t *testing.T) {
bst := NewBST(1, compareFunc)

bst.Insert(3)
bst.Insert(2)
bst.Insert(5)

t.Log(bst.Delete(1))

bst.InOrderTraverse()
}
func TestBST_DeleteE(t *testing.T) {
bst := NewBST(5, compareFunc)

bst.Insert(3)
bst.Insert(2)
bst.Insert(4)
bst.Insert(1)

t.Log(bst.Delete(5))
bst.InOrderTraverse()
}

func TestBST_DeleteF(t *testing.T) {
bst := NewBST(5, compareFunc)

bst.Insert(3)
bst.Insert(2)
bst.Insert(4)
bst.Insert(1)

t.Log(bst.Delete(2))
bst.InOrderTraverse()
}

func TestBST_DeleteG(t *testing.T) {
bst := NewBST(5, compareFunc)

bst.Insert(3)
bst.Insert(2)
bst.Insert(4)
bst.Insert(1)

t.Log(bst.Delete(1))
bst.InOrderTraverse()
}
65 changes: 65 additions & 0 deletions go/24_tree/BinaryTree.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package _4_tree

import "fmt"

type BinaryTree struct {
root *Node
}

func NewBinaryTree(rootV interface{}) *BinaryTree {
return &BinaryTree{NewNode(rootV)}
}

func (this *BinaryTree) InOrderTraverse() {
p := this.root
s := NewArrayStack()

for !s.IsEmpty() || nil != p {
if nil != p {
s.Push(p)
p = p.left
} else {
tmp := s.Pop().(*Node)
fmt.Printf("%+v ", tmp.data)
p = tmp.right
}
}
fmt.Println()
}

func (this *BinaryTree) PreOrderTraverse() {
p := this.root
s := NewArrayStack()

for !s.IsEmpty() || nil != p {
if nil != p {
fmt.Printf("%+v ", p.data)
s.Push(p)
p = p.left
} else {
p = s.Pop().(*Node).right
}
}

fmt.Println()
}

func (this *BinaryTree) PostOrderTraverse() {
s1 := NewArrayStack()
s2 := NewArrayStack()
s1.Push(this.root)
for !s1.IsEmpty() {
p := s1.Pop().(*Node)
s2.Push(p)
if nil != p.left {
s1.Push(p.left)
}
if nil != p.right {
s1.Push(p.right)
}
}

for !s2.IsEmpty() {
fmt.Printf("%+v ", s2.Pop().(*Node).data)
}
}
30 changes: 30 additions & 0 deletions go/24_tree/BinaryTree_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package _4_tree

import "testing"

func TestBinaryTree_InOrderTraverse(t *testing.T) {
binaryTree := NewBinaryTree(1)
binaryTree.root.left = NewNode(3)
binaryTree.root.right = NewNode(4)
binaryTree.root.right.left = NewNode(5)

binaryTree.InOrderTraverse()
}

func TestBinaryTree_PreOrderTraverse(t *testing.T) {
binaryTree := NewBinaryTree(1)
binaryTree.root.left = NewNode(3)
binaryTree.root.right = NewNode(4)
binaryTree.root.right.left = NewNode(5)

binaryTree.PreOrderTraverse()
}

func TestBinaryTree_PostOrderTraverse(t *testing.T) {
binaryTree := NewBinaryTree(1)
binaryTree.root.left = NewNode(3)
binaryTree.root.right = NewNode(4)
binaryTree.root.right.left = NewNode(5)

binaryTree.PostOrderTraverse()
}
Loading

0 comments on commit 1ac0b0a

Please sign in to comment.