package main 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() fmt.Println() 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 = node.left.Insert(name, phone) } else if name > node.name { node.right = node.right.Insert(name, phone) } else { node.phone = phone // Заменяем существующее значение } return node } // Delete удаляет узел по имени. // Возвращает нового потомка для родительского узла. /* Node delete(root : Node, z : T): // корень поддерева, удаляемый ключ if root == null return root if z < root.key root.left = delete(root.left, z) else if z > root.key root.right = delete(root.right, z) else if root.left != null and root.right != null root.key = minimum(root.right).key root.right = delete(root.right, root.key) else if root.left != null root = root.left else if root.right != null root = root.right else root = null return root */ 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 { return root.left } else if root.right != nil { return root.right } else { return nil } } 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) }