forked from UNN/2026-rff_mp
Изменил работу со структурами, чтобы они походили под интерфейсы
This commit is contained in:
parent
bc6ece83d0
commit
b3688d3ed9
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user