169 lines
3.6 KiB
Go
169 lines
3.6 KiB
Go
package binsearchtree
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
type BinSearchTree struct {
|
|
name string
|
|
phone string
|
|
|
|
left *BinSearchTree
|
|
right *BinSearchTree
|
|
}
|
|
|
|
func NewBinSearchTree(name, phone string) *BinSearchTree {
|
|
return &BinSearchTree{
|
|
name: name,
|
|
phone: phone,
|
|
left: nil,
|
|
right: nil,
|
|
}
|
|
}
|
|
|
|
func (bst *BinSearchTree) Minimum() *BinSearchTree {
|
|
if bst.left == nil {
|
|
return bst
|
|
}
|
|
return bst.left.Minimum()
|
|
}
|
|
func (bst *BinSearchTree) Maximum() *BinSearchTree {
|
|
if bst.right == nil {
|
|
return bst
|
|
}
|
|
return bst.right.Maximum()
|
|
}
|
|
|
|
func (node *BinSearchTree) PrintNode() {
|
|
fmt.Printf("Имя: %s, Телефон: %s", node.name, node.phone)
|
|
}
|
|
|
|
func (node *BinSearchTree) ToString() string {
|
|
if node == nil {
|
|
return "nil"
|
|
}
|
|
return fmt.Sprintf("Имя: %s, Телефон: %s", node.name, node.phone)
|
|
}
|
|
|
|
func (bst *BinSearchTree) BstInorderTraversal() {
|
|
if bst != nil {
|
|
bst.left.BstInorderTraversal()
|
|
bst.PrintNode()
|
|
bst.right.BstInorderTraversal()
|
|
}
|
|
}
|
|
|
|
func (bst *BinSearchTree) BstPreorderTraversal() {
|
|
if bst != nil {
|
|
bst.PrintNode()
|
|
bst.left.BstPreorderTraversal()
|
|
bst.right.BstPreorderTraversal()
|
|
}
|
|
}
|
|
|
|
// Search
|
|
// Возвращает строковое представление узла
|
|
func (bst *BinSearchTree) Search(targetName string) (string, bool) {
|
|
node, ok := bst.search(targetName)
|
|
if ok {
|
|
return node.ToString(), true
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
/*
|
|
Node search(x : Node, k : T):
|
|
if x == null or k == x.key
|
|
return x
|
|
if k < x.key
|
|
return search(x.left, k)
|
|
else
|
|
return search(x.right, k)
|
|
*/
|
|
// Приватная вспомогательная функция поиска
|
|
func (node *BinSearchTree) search(targetName string) (*BinSearchTree, bool) {
|
|
if node == nil {
|
|
return nil, false
|
|
}
|
|
if node.name == targetName {
|
|
return node, true
|
|
}
|
|
if targetName < node.name {
|
|
return node.left.search(targetName)
|
|
}
|
|
return node.right.search(targetName)
|
|
}
|
|
|
|
// func (bst *BinSearchTree) Search(targetName string) (string, bool) {
|
|
/*
|
|
Node search(x : Node, k : T):
|
|
if x == null or k == x.key
|
|
return x
|
|
if k < x.key
|
|
return search(x.left, k)
|
|
else
|
|
return search(x.right, k)
|
|
*/
|
|
// targetNode, ok := bst.head.search(targetName)
|
|
|
|
// return targetNode.ToString(), ok
|
|
// }
|
|
|
|
func (node *BinSearchTree) Insert(name, phone string) *BinSearchTree {
|
|
if node == nil {
|
|
return NewBinSearchTree(name, phone)
|
|
} else if name < node.name {
|
|
node.left.Insert(name, phone)
|
|
} else if name > node.name {
|
|
node.right.Insert(name, phone)
|
|
} else {
|
|
node.phone = phone // Заменяем существующее значение
|
|
}
|
|
return node
|
|
}
|
|
|
|
// Delete удаляет узел по имени.
|
|
// Возвращает нового потомка для родительского узла.
|
|
func (root *BinSearchTree) Delete(targetName string) *BinSearchTree {
|
|
if root == nil {
|
|
return nil
|
|
}
|
|
|
|
if targetName < root.name {
|
|
root.left = root.left.Delete(targetName)
|
|
} else if targetName > root.name {
|
|
root.right = root.right.Delete(targetName)
|
|
} else {
|
|
if root.left != nil && root.right != nil {
|
|
temp := root.right.Minimum()
|
|
root.name = root.right.Minimum().name
|
|
root.phone = root.right.Minimum().phone
|
|
// strcpy(root->name, bst_minimum(root->right)->name);
|
|
// strcpy(root->phone, bst_minimum(root->right)->phone);
|
|
|
|
root.right = root.right.Delete(temp.name)
|
|
} else {
|
|
if root.left != nil {
|
|
root = root.left
|
|
} else {
|
|
root = root.right
|
|
}
|
|
}
|
|
}
|
|
return root
|
|
}
|
|
|
|
func (bst *BinSearchTree) PrintAll(depth int) {
|
|
if bst == nil {
|
|
return
|
|
}
|
|
|
|
bst.right.PrintAll(depth + 1)
|
|
|
|
for i := 0; i < depth; i++ {
|
|
fmt.Printf("\t")
|
|
}
|
|
bst.PrintNode()
|
|
bst.left.PrintAll(depth + 1)
|
|
}
|