—————————————–binarysearchtree.go—————————————-
package binarysearchtree import ( "fmt" "container/list" "errors" ) var ( ErrComparatorIsNil = errors.New("comparator of BinarySearchTree is nil") ErrTreeIsEmpty = errors.New("BinarySearchTree is empty") ) type ( Comparator interface { Compare(x interface{}, y *BinaryNode) int } BinaryNode struct { Val interface{} Left, Right *BinaryNode } BinarySearchTree struct { Root *BinaryNode Comparator Comparator } ) // 创建二叉搜索树时必须提供排序规则 func New(comparator Comparator) *BinarySearchTree { if comparator == nil { panic(ErrComparatorIsNil) } return &BinarySearchTree{nil, comparator} } // 清空数据 func (tree *BinarySearchTree) MakeEmpty() { tree.Root = nil } func (tree *BinarySearchTree) IsEmpty() bool { return tree.Root == nil } func (tree *BinarySearchTree) Contains(x interface{}) (bool, error) { return tree.contains(x, tree.Root) } // 递归查找是否包含某值 func (tree *BinarySearchTree) contains(x interface{}, root *BinaryNode) (bool, error) { if root == nil { return false, nil } if tree.Comparator == nil { return false, ErrComparatorIsNil } compareResult := tree.Comparator.Compare(x, root) if compareResult < 0 { return tree.contains(x, root.Left) } else if compareResult > 0 { return tree.contains(x, root.Right) } else { return true, nil } } // 递归查找最小值 最小值只能在左子树上,因此只需要递归左子树即可 func (tree *BinarySearchTree) FindMin() (*BinaryNode, error) { if tree.IsEmpty() { return nil, ErrTreeIsEmpty } return tree.findMin(tree.Root), nil } func (tree *BinarySearchTree) findMin(root *BinaryNode) *BinaryNode { if root == nil { return nil } else if root.Left == nil { return root } return tree.findMin(root.Left) } // 使用非递归的方式查找最大值 最大值只能在右子树上的最后的叶子节点 func (tree *BinarySearchTree) FindMax() (*BinaryNode, error) { if tree.IsEmpty() { return nil, ErrTreeIsEmpty } root := tree.Root for ; root.Right != nil; { root = root.Right } return root, nil } // 插入值val 同contains方法一样遍历树,如果找到相同的值不做任何操作,如果比当前节点值大,递归其插入左子树,否则插入又子树 func (tree *BinarySearchTree) Insert(val interface{}) { tree.Root = tree.insert(val, tree.Root) } func (tree *BinarySearchTree) insert(val interface{}, root *BinaryNode) *BinaryNode { if root == nil { return &BinaryNode{val, nil, nil} } compareResult := tree.Comparator.Compare(val, root) if compareResult < 0 { root.Left = tree.insert(val, root.Left) } else if compareResult > 0 { root.Right = tree.insert(val, root.Right) } else { //重复值,不做操作 } return root } // 删除操作最为复杂 // 先递归查找到要删除的元素 // 然后分为:叶子节点,左子树为nil,右子树为nil,左右均不为nil四种情况 func (tree *BinarySearchTree) Remove(val interface{}) *BinaryNode { return tree.remove(val, tree.Root, nil) } func (tree *BinarySearchTree) remove(val interface{}, root, parent *BinaryNode) (*BinaryNode) { if root == nil { return nil } compareResult := tree.Comparator.Compare(val, root) if compareResult < 0 { return tree.remove(val, root.Left, root) } else if compareResult > 0 { return tree.remove(val, root.Right, root) } else { ret := &BinaryNode{Val: root.Val} // 左右子树有任意一个为空,用另外一个替换掉当前节点即可 if root.Left == nil { tree.replaceChild(parent, val, root.Right) return ret } if root.Right == nil { tree.replaceChild(parent, val, root.Left) return ret } // 左右子树均不为空,则将右子树中的最小值替换当前节点,并从又子树中删掉该最小值即可 rightMin := tree.findMin(root.Right) root.Val = rightMin.Val tree.replaceChild(root.Right, rightMin.Val, rightMin.Right) return ret } } // 给定的值是左子节点的值,则替换左节点,否则替换右节点 func (tree *BinarySearchTree) replaceChild(parent *BinaryNode, oldVal interface{}, theNode *BinaryNode) { if parent == nil { return } if tree.Comparator.Compare(oldVal, parent.Left) == 0 { parent.Left = theNode } else { parent.Right = theNode } } // 层序遍历输出 func (tree *BinarySearchTree) Print() { if tree.IsEmpty() { return } // 使用go官方包里的list模拟队列的操作 l := list.New() l.PushBack(tree.Root) for ; l.Len() > 0; { element := l.Front() l.Remove(element) if node, ok := element.Value.(*BinaryNode); ok && node != nil { l.PushBack(node.Left) l.PushBack(node.Right) fmt.Printf("%v\t", node.Val) } } }
————————————-binarysearchtree_test.go————————————-
package binarysearchtree import ( "testing" "fmt" ) type IntComparator struct { } func (this IntComparator) Compare(x interface{}, y *BinaryNode) int { if y == nil { if x == nil { return 0 } else { return 1 } } if x == nil { return -1 } return x.(int) - y.Val.(int) } func TestBinarySearchTree(t *testing.T) { tree := New(IntComparator{}) tree.Insert(6) tree.Insert(2) tree.Insert(8) tree.Insert(1) tree.Insert(4) tree.Insert(3) tree.Remove(2) fmt.Println(tree.Contains(4)) tree.Print() }