diff --git a/stepushovgs/data-structures/sorce/bin_search_tree/bst.go b/stepushovgs/data-structures/sorce/bin_search_tree/bst.go index 78d60b8..fdc8527 100644 --- a/stepushovgs/data-structures/sorce/bin_search_tree/bst.go +++ b/stepushovgs/data-structures/sorce/bin_search_tree/bst.go @@ -1,4 +1,4 @@ -package binsearchtree +package main import ( "fmt" @@ -49,6 +49,7 @@ func (bst *BinSearchTree) BstInorderTraversal() { if bst != nil { bst.left.BstInorderTraversal() bst.PrintNode() + fmt.Println() bst.right.BstInorderTraversal() } } @@ -113,9 +114,9 @@ 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) + node.left = node.left.Insert(name, phone) } else if name > node.name { - node.right.Insert(name, phone) + node.right = node.right.Insert(name, phone) } else { node.phone = phone // Заменяем существующее значение } @@ -124,6 +125,28 @@ func (node *BinSearchTree) Insert(name, phone string) *BinSearchTree { // 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 @@ -133,21 +156,21 @@ func (root *BinSearchTree) Delete(targetName string) *BinSearchTree { 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); + } else if root.left != nil && root.right != nil { + temp := root.right.Minimum() + root.name = root.right.Minimum().name + root.phone = root.right.Minimum().phone - root.right = root.right.Delete(temp.name) + // 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 { - if root.left != nil { - root = root.left - } else { - root = root.right - } + return nil } } return root diff --git a/stepushovgs/data-structures/sorce/bin_search_tree/main.go b/stepushovgs/data-structures/sorce/bin_search_tree/main.go new file mode 100644 index 0000000..07ff05e --- /dev/null +++ b/stepushovgs/data-structures/sorce/bin_search_tree/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "fmt" + "math/rand" +) + +const ( + countNumbers = 64 +) + +// isInArr проверяет, содержится ли target в срезе arr[:len] +func isInArr(arr []int, length int, target int) bool { + for i := 0; i < length; i++ { + if arr[i] == target { + return true + } + } + return false +} + +func main() { + fmt.Println("hello world!") + + var head *BinSearchTree = nil + + arr := make([]int, countNumbers) + + var temp int + for i := 0; i < countNumbers; i++ { + // Генерируем уникальное случайное число + for { + temp = rand.Intn(100) // 0 до 99 + if !isInArr(arr, i, temp) { + break + } + } + + arr[i] = temp + + nameStr := fmt.Sprintf("name_%02d", temp) + phoneStr := fmt.Sprintf("phone_%02d", temp) + + head = head.Insert(nameStr, phoneStr) + fmt.Printf("%d ", arr[i]) + } + + fmt.Printf("\n\nКоличество узлов: %d\n", countNodes(head)) + + fmt.Println("\ninorder traversal:") + head.BstInorderTraversal() + + tarName := "name_44" + + fmt.Printf("\nПоиск '%s' перед удалением: ", tarName) + if found, ok := head.Search(tarName); ok { + fmt.Printf("Найден: %s\n", found) + } else { + fmt.Printf("НЕ найден!\n") + } + + fmt.Printf("\nУдаляем элемент с значением %s:\n", tarName) + + head = head.Delete(tarName) + + fmt.Printf("\nКоличество узлов после удаления: %d\n", countNodes(head)) + + fmt.Printf("Поиск '%s' после удаления: ", tarName) + if found, ok := head.Search(tarName); ok { + fmt.Printf("ОШИБКА! Все еще существует: %s\n", found) + } else { + fmt.Printf("Успешно удален\n") + } + + fmt.Println("\ninorder traversal after delete:") + head.BstInorderTraversal() +} + +func countNodes(root *BinSearchTree) int { + if root == nil { + return 0 + } + return 1 + countNodes(root.left) + countNodes(root.right) +}