Изменил работу со структурами, чтобы они походили под интерфейсы

This commit is contained in:
GordStep 2026-05-13 21:25:29 +03:00
parent bc6ece83d0
commit b3688d3ed9
4 changed files with 177 additions and 116 deletions

View File

@ -6,14 +6,18 @@ import (
) )
type BinSearchTree struct { type BinSearchTree struct {
data ds.MyData root *BSTree
left *BinSearchTree
right *BinSearchTree
} }
func NewBinSearchTree(data ds.MyData) *BinSearchTree { type BSTree struct {
return &BinSearchTree{ data ds.MyData
left *BSTree
right *BSTree
}
func NewBinSearchTree(data ds.MyData) *BSTree {
return &BSTree{
data: data, data: data,
left: nil, left: nil,
right: nil, right: nil,
@ -21,30 +25,42 @@ func NewBinSearchTree(data ds.MyData) *BinSearchTree {
} }
func (bst *BinSearchTree) Len() int { func (bst *BinSearchTree) Len() int {
return bst.root.Len()
}
func (bst *BSTree) Len() int {
if bst == nil { if bst == nil {
return 0 return 0
} }
return 1 + bst.left.Len() + bst.right.Len() return 1 + bst.left.Len() + bst.right.Len()
} }
func (bst *BinSearchTree) Minimum() *BinSearchTree { func (bst *BinSearchTree) Minimum() *BSTree {
if bst.left == nil { return bst.root.Minimum()
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() { func (root *BSTree) Minimum() *BSTree {
if root.left == nil {
return root
}
return root.left.Minimum()
}
func (bst *BinSearchTree) Maximum() *BSTree {
return bst.root.Maximum()
}
func (root *BSTree) Maximum() *BSTree {
if root.right == nil {
return root
}
return root.right.Maximum()
}
func (node *BSTree) PrintNode() {
fmt.Print(node.data.ToString()) fmt.Print(node.data.ToString())
} }
func (node *BinSearchTree) ToString() string { func (node *BSTree) ToString() string {
if node == nil { if node == nil {
return "nil" return "nil"
} }
@ -52,28 +68,37 @@ func (node *BinSearchTree) ToString() string {
} }
func (bst *BinSearchTree) BstInorderTraversal() { func (bst *BinSearchTree) BstInorderTraversal() {
if bst != nil { bst.root.BstInorderTraversal()
bst.left.BstInorderTraversal() }
bst.PrintNode()
func (root *BSTree) BstInorderTraversal() {
if root != nil {
root.left.BstInorderTraversal()
root.PrintNode()
fmt.Println() fmt.Println()
bst.right.BstInorderTraversal() root.right.BstInorderTraversal()
} }
} }
func (bst *BinSearchTree) BstPreorderTraversal() { func (bst *BinSearchTree) BstPreorderTraversal() {
if bst != nil { bst.root.BstPreorderTraversal()
bst.PrintNode() }
bst.left.BstPreorderTraversal()
bst.right.BstPreorderTraversal() func (root *BSTree) BstPreorderTraversal() {
if root != nil {
root.PrintNode()
fmt.Println()
root.left.BstPreorderTraversal()
root.right.BstPreorderTraversal()
} }
} }
// Search // Search
// Возвращает строковое представление узла // Возвращает номер телефона по имени
func (bst *BinSearchTree) Search(targetName string) (string, bool) { func (bst *BinSearchTree) Search(targetName string) (string, bool) {
node, ok := bst.search(targetName) node, ok := bst.root.search(targetName)
if ok { if ok {
return node.ToString(), true return node.data.Phone, true
} }
return "", false return "", false
} }
@ -88,7 +113,7 @@ func (bst *BinSearchTree) Search(targetName string) (string, bool) {
return search(x.right, k) return search(x.right, k)
*/ */
// Приватная вспомогательная функция поиска // Приватная вспомогательная функция поиска
func (node *BinSearchTree) search(targetName string) (*BinSearchTree, bool) { func (node *BSTree) search(targetName string) (*BSTree, bool) {
if node == nil { if node == nil {
return nil, false return nil, false
} }
@ -101,32 +126,38 @@ func (node *BinSearchTree) search(targetName string) (*BinSearchTree, bool) {
return node.right.search(targetName) return node.right.search(targetName)
} }
// func (bst *BinSearchTree) Search(targetName string) (string, bool) { // func (node *BinSearchTree) Insert(data ds.MyData) *BinSearchTree {
/* // if node == nil {
Node search(x : Node, k : T): // return NewBinSearchTree(data)
if x == null or k == x.key // } else if data.Name < node.data.Name {
return x // node.left = node.left.Insert(data)
if k < x.key // } else if data.Name > node.data.Name {
return search(x.left, k) // node.right = node.right.Insert(data)
else // } else {
return search(x.right, k) // node.data.Phone = data.Phone // Заменяем существующее значение
*/ // }
// targetNode, ok := bst.head.search(targetName) // return node
// return targetNode.ToString(), ok
// } // }
func (node *BinSearchTree) Insert(data ds.MyData) *BinSearchTree { func (bst *BinSearchTree) Insert(data ds.MyData) {
if node == nil { bst.root = bst.root.insert(data)
return NewBinSearchTree(data)
} else if data.Name < node.data.Name {
node.left = node.left.Insert(data)
} else if data.Name > node.data.Name {
node.right = node.right.Insert(data)
} else {
node.data.Phone = data.Phone // Заменяем существующее значение
} }
return node
func (root *BSTree) insert(data ds.MyData) *BSTree {
if root == nil {
return &BSTree{
data: data,
}
}
if data.Name < root.data.Name {
root.left = root.left.insert(data)
} else if data.Name > root.data.Name {
root.right = root.right.insert(data)
} else {
root.data.Phone = data.Phone
}
return root
} }
// Delete удаляет узел по имени. // Delete удаляет узел по имени.
@ -153,45 +184,59 @@ Node delete(root : Node, z : T): // корень поддерев
return root return root
*/ */
func (root *BinSearchTree) Delete(targetName string) *BinSearchTree { func (bst *BinSearchTree) Delete(targetName string) bool {
if bst.root == nil {
return false
}
bst.root = bst.root.delete(targetName)
return true
}
func (root *BSTree) delete(targetName string) *BSTree {
if root == nil { if root == nil {
return nil return nil
} }
if targetName < root.data.Name { if targetName < root.data.Name {
root.left = root.left.Delete(targetName) root.left = root.left.delete(targetName)
} else if targetName > root.data.Name { } else if targetName > root.data.Name {
root.right = root.right.Delete(targetName) root.right = root.right.delete(targetName)
} else if root.left != nil && root.right != nil { } else {
temp := root.right.Minimum() // Нашли узел для удаления
root.data.Name = root.right.Minimum().data.Name
root.data.Phone = root.right.Minimum().data.Phone
// strcpy(root->name, bst_minimum(root->right)->name); // Случай 1: нет левого потомка
// strcpy(root->phone, bst_minimum(root->right)->phone); if root.left == nil {
root.right = root.right.Delete(temp.data.Name)
} else {
if root.left != nil {
return root.left
} else if root.right != nil {
return root.right return root.right
} else {
return nil
} }
// Случай 2: нет правого потомка
if root.right == nil {
return root.left
} }
// Случай 3: оба потомка есть
successor := root.right.Minimum()
root.data = successor.data // Копируем все данные сразу
root.right = root.right.delete(successor.data.Name)
}
return root return root
} }
func (bst *BinSearchTree) PrintAll(depth int) { func (bst *BinSearchTree) PrintAll() {
bst.root.printAll(0)
}
func (bst *BSTree) printAll(depth int) {
if bst == nil { if bst == nil {
return return
} }
bst.right.PrintAll(depth + 1) bst.right.printAll(depth + 1)
for i := 0; i < depth; i++ { for i := 0; i < depth; i++ {
fmt.Printf("\t") fmt.Printf("\t")
} }
bst.PrintNode() bst.PrintNode()
bst.left.PrintAll(depth + 1) bst.left.printAll(depth + 1)
} }

View File

@ -1,9 +1,7 @@
package hash_table package hash_table
import ( import (
"bufio"
"fmt" "fmt"
"os"
ds "source/pkg/data_struct" ds "source/pkg/data_struct"
) )
@ -54,6 +52,10 @@ func (ht *HashTable) GetIndex(name string) int {
return hash % ht.capacity return hash % ht.capacity
} }
func (ht *HashTable) Len() int {
return ht.size
}
// func (ht *HashTable) getIndex(hash int) int { // func (ht *HashTable) getIndex(hash int) int {
// return hash % ht.capacity // return hash % ht.capacity
// } // }
@ -88,7 +90,7 @@ func (h *HashTable) Insert(new ds.MyData) {
h.size++ h.size++
} }
func (h *HashTable) Get(name string) (phone string, status bool) { func (h *HashTable) Search(name string) (phone string, status bool) {
ind := h.GetIndex(name) ind := h.GetIndex(name)
buck := h.buckets[ind] buck := h.buckets[ind]
@ -106,10 +108,10 @@ func (h *HashTable) Get(name string) (phone string, status bool) {
return "", false return "", false
} }
func pressEnterToContinue() { // func pressEnterToContinue() {
fmt.Print("Нажмите Enter для продолжения...") // fmt.Print("Нажмите Enter для продолжения...")
bufio.NewReader(os.Stdin).ReadBytes('\n') // bufio.NewReader(os.Stdin).ReadBytes('\n')
} // }
// resize - увеличивает размер таблицы // resize - увеличивает размер таблицы
func (ht *HashTable) resize() { func (ht *HashTable) resize() {
@ -135,7 +137,7 @@ func (ht *HashTable) resize() {
ht.capacity = newCapacity ht.capacity = newCapacity
} }
func (ht *HashTable) Remove(name string) bool { func (ht *HashTable) Delete(name string) bool {
ind := ht.GetIndex(name) ind := ht.GetIndex(name)
buck := ht.buckets[ind] buck := ht.buckets[ind]
@ -167,7 +169,7 @@ func (ht *HashTable) Remove(name string) bool {
} }
func (ht *HashTable) Contains(name string) bool { func (ht *HashTable) Contains(name string) bool {
_, ok := ht.Get(name) _, ok := ht.Search(name)
return ok return ok
} }

View File

@ -22,19 +22,26 @@ def ll_list_all(head) — собирает все записи в список
*/ */
type LinkedList struct { type LinkedList struct {
data ds.MyData head *LList
next *LinkedList
} }
func NewLinkedList(data ds.MyData) *LinkedList { type LList struct {
return &LinkedList{ data ds.MyData
next *LList
}
func NewLinkedList(data ds.MyData) *LList {
return &LList{
data: data, data: data,
next: nil, next: nil,
} }
} }
func (ll *LinkedList) ToString() string { func (ll *LList) ToString() string {
if ll == nil {
return "nil"
}
return ll.data.ToString() return ll.data.ToString()
} }
@ -45,7 +52,7 @@ func (ll *LinkedList) Len() int {
} }
len := 0 len := 0
current := ll current := ll.head
for current != nil { for current != nil {
len++ len++
current = current.next current = current.next
@ -54,23 +61,23 @@ func (ll *LinkedList) Len() int {
return len return len
} }
func (ll *LinkedList) Insert(data ds.MyData) *LinkedList { func (ll *LinkedList) Insert(data ds.MyData) {
newNode := NewLinkedList(data) newNode := NewLinkedList(data)
if ll == nil { if ll.head == nil {
return newNode ll.head = newNode
return
} }
current := ll current := ll.head
for current.next != nil { for current.next != nil {
current = current.next current = current.next
} }
current.next = newNode current.next = newNode
return ll
} }
func (ll *LinkedList) Search(targetName string) (string, bool) { func (ll *LinkedList) Search(targetName string) (string, bool) {
current := ll current := ll.head
for current != nil { for current != nil {
if current.data.Name == targetName { if current.data.Name == targetName {
@ -83,7 +90,7 @@ func (ll *LinkedList) Search(targetName string) (string, bool) {
} }
func (ll *LinkedList) PrintAll() { func (ll *LinkedList) PrintAll() {
current := ll current := ll.head
index := 0 index := 0
for current != nil { for current != nil {
@ -93,33 +100,33 @@ func (ll *LinkedList) PrintAll() {
} }
} }
func (ll *LinkedList) Delete(targetName string) (*LinkedList, bool) { func (ll *LinkedList) Delete(targetName string) bool {
if ll.head == nil {
if ll == nil { return false
return nil, false
}
if ll.data.Name == targetName {
ll.data = ll.next.data
ll.next = ll.next.next
return ll, true
} }
prev := ll // Особый случай: удаление головы списка
current := ll.next if ll.head.data.Name == targetName {
// Сдвигаем данные и указатель
for current != nil { *ll.head = *ll.head.next
if current.data.Name == targetName { return true
prev.next = current.next }
// Стандартное удаление из середины/конца
current := ll.head
for current.next != nil {
if current.next.data.Name == targetName {
current.next = current.next.next
return true
} }
prev = current
current = current.next current = current.next
} }
return ll, false return false
} }
func (ll *LinkedList) listAll() []ds.MyData { func (ll *LinkedList) listAll() []ds.MyData {
current := ll current := ll.head
listLL := make([]ds.MyData, ll.Len()) listLL := make([]ds.MyData, ll.Len())
ind := 0 ind := 0
@ -139,7 +146,7 @@ func (ll *LinkedList) GetByInd(ind int) (ds.MyData, bool) {
} }
index := 0 index := 0
current := ll current := ll.head
for current != nil { for current != nil {
if index == ind { if index == ind {
return current.data, true return current.data, true

View File

@ -6,6 +6,8 @@ import (
csvwriter "source/pkg/csv_writer" csvwriter "source/pkg/csv_writer"
ds "source/pkg/data_struct" ds "source/pkg/data_struct"
dg "source/pkg/gen_data" dg "source/pkg/gen_data"
bst "source/pkg/structures/bin_search_tree"
ht "source/pkg/structures/hash_table"
ll "source/pkg/structures/linked_list" ll "source/pkg/structures/linked_list"
// csv "source/pkg/csv_ri" // csv "source/pkg/csv_ri"
@ -31,9 +33,9 @@ type TestData struct {
type DataStructure interface { type DataStructure interface {
Insert(data ds.MyData) Insert(data ds.MyData)
Search(name string) *ds.MyData Search(name string) (string, bool)
Delete(name string) bool Delete(name string) bool
Size() int Len() int
} }
func uniqueElements(data []ds.MyData) []ds.MyData { func uniqueElements(data []ds.MyData) []ds.MyData {
@ -89,6 +91,7 @@ func GenerateTestData() TestData {
} }
} }
// Тест вставки массива данных (один раз)
func testOneInsert(structure DataStructure, data []ds.MyData) float64 { func testOneInsert(structure DataStructure, data []ds.MyData) float64 {
start := time.Now() start := time.Now()
@ -147,6 +150,10 @@ func main() {
testData := GenerateTestData() testData := GenerateTestData()
var head_ll *ll.LinkedList = nil var head_ll *ll.LinkedList = nil
var head_ht *ht.HashTable = nil
var head_bst *bst.BinSearchTree = nil
Test("Связный список", head_ll, testData) Test("Связный список", head_ll, testData)
Test("Связный список", head_ht, testData)
Test("Связный список", head_bst, testData)
} }