algorithms-go/DataStructure/tree/binaryTree/bst.go

170 lines
2.4 KiB
Go
Raw Normal View History

2021-04-07 18:13:02 +08:00
package binaryTree
//二叉树
//二叉树是每个节点最多有两个子树的树结构
type ElementType int //节点数据
//结点
type Node struct {
Value ElementType
Parent *Node
Left *Node
Right *Node
}
//创建节点
func NewNode(v ElementType) *Node {
return &Node{Value: v}
}
/*
*节点比较
* n>m:1 n<m:-1 n=m:0
*/
func (n *Node) Compare(m *Node) int {
if n.Value < m.Value {
return -1
} else if n.Value > m.Value {
return 1
} else {
return 0
}
}
//树
type Tree struct {
Head *Node
Size int
}
//创建树
func NewTree(n *Node) *Tree {
if n == nil {
return &Tree{}
}
return &Tree{Head: n, Size: 1}
}
//插入,相同的节点值,放到右子树
func (t *Tree) Insert(i ElementType) {
n := NewNode(i) //创建节点
if t.Head == nil { //判断树的根节点
t.Head = n
t.Size++
return
}
h := t.Head
for {
if n.Compare(h) == -1 { //小于parent到左子节点
if h.Left == nil { //无左子节点
h.Left = n
n.Parent = h
break
} else {
h = h.Left
}
} else { //大于parent
if h.Right == nil {
h.Right = n
n.Parent = h
break
} else {
h = h.Right
}
}
}
t.Size++
}
//搜索
func (t *Tree) Search(i ElementType) *Node {
h := t.Head
n := NewNode(i)
for h != nil {
switch h.Compare(n) {
case -1:
h = h.Right
case 1:
h = h.Left
case 0:
return h
default:
panic("Node not found")
}
}
panic("Node not found")
}
//删除
func (t *Tree) Delete(i ElementType) bool {
var parent *Node
h := t.Head
n := NewNode(i)
for h != nil {
switch n.Compare(h) {
case -1:
parent = h
h = h.Left
case 1:
parent = h
h = h.Right
case 0:
if h.Left != nil {
right := h.Right
h.Value = h.Left.Value
h.Left = h.Left.Left
h.Right = h.Left.Right
if right != nil {
subTree := &Tree{Head: h}
IterOnTree(right, func(n *Node) {
subTree.Insert(n.Value)
})
}
t.Size--
return true
}
if h.Right != nil {
h.Value = h.Right.Value
h.Left = h.Right.Left
h.Right = h.Right.Right
t.Size--
return true
}
if parent == nil {
t.Head = nil
t.Size--
return true
}
if parent.Left == n {
parent.Left = nil
} else {
parent.Right = nil
}
t.Size--
return true
}
}
return false
}
func IterOnTree(n *Node, f func(*Node)) bool {
if n == nil {
return true
}
if !IterOnTree(n.Left, f) {
return false
}
f(n)
return IterOnTree(n.Right, f)
}