From 58af1a12120dff920688aab3986fb4e87d38f34b Mon Sep 17 00:00:00 2001 From: Mamoru777 Date: Thu, 30 May 2024 11:50:30 +0400 Subject: [PATCH] Done --- .idea/.gitignore | 8 ++++ .idea/Ex_GoAlgorithms.iml | 9 ++++ .idea/modules.xml | 8 ++++ .idea/vcs.xml | 6 +++ binaryTreeInsertDelete.go | 96 +++++++++++++++++++++++++++++++++++++++ binaryTreeInsertPrint.go | 61 +++++++++++++++++++++++++ circularLinkedList.go | 46 +++++++++++++++++++ doublyLinkedList.go | 36 +++++++++++++++ graphList.go | 26 +++++++++++ graphWidth.go | 22 +++++++++ hashTableChains.go | 89 ++++++++++++++++++++++++++++++++++++ hashTableOpen.go | 60 ++++++++++++++++++++++++ main.go | 89 ++++++++++++++++++++++++++++++++++++ 13 files changed, 556 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/Ex_GoAlgorithms.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 binaryTreeInsertDelete.go create mode 100644 binaryTreeInsertPrint.go create mode 100644 circularLinkedList.go create mode 100644 doublyLinkedList.go create mode 100644 graphList.go create mode 100644 graphWidth.go create mode 100644 hashTableChains.go create mode 100644 hashTableOpen.go create mode 100644 main.go diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Ex_GoAlgorithms.iml b/.idea/Ex_GoAlgorithms.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/Ex_GoAlgorithms.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..578cc2a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/binaryTreeInsertDelete.go b/binaryTreeInsertDelete.go new file mode 100644 index 0000000..5f76262 --- /dev/null +++ b/binaryTreeInsertDelete.go @@ -0,0 +1,96 @@ +package main + +import "fmt" + +type BinaryNode2 struct { + Key int + Left *BinaryNode2 + Right *BinaryNode2 +} + +func (n *BinaryNode2) Insert(key int) { + // если входной ключ больше, то идем вправо + if n.Key < key { + if n.Right == nil { + n.Right = &BinaryNode2{Key: key} + } else { + n.Right.Insert(key) + } + } else if n.Key > key { + // иначе идем влево + if n.Left == nil { + n.Left = &BinaryNode2{Key: key} + } else { + n.Left.Insert(key) + } + } +} + +func (n *BinaryNode2) MinNode() *BinaryNode2 { + current := n + + // цикл, ищущий самый левый лист + for current.Left != nil { + current = current.Left + } + return current +} + +func (n *BinaryNode2) Delete(key int) *BinaryNode2 { + if n == nil { + return nil + } + + // если входной ключ меньше, то находится в левом поддереве + if key < n.Key { + n.Left = n.Left.Delete(key) + } else if key > n.Key { + n.Right = n.Right.Delete(key) + } else { + // узел с одним ребенком или без ребенка + if n.Left == nil { + return n.Right + } else if n.Right == nil { + return n.Left + } + + // узел с двумя детьми: получить минимальный узел в правом поддереве + minRight := n.Right.MinNode() + n.Key = minRight.Key + n.Right = n.Right.Delete(minRight.Key) + } + + return n +} + +func (n *BinaryNode2) InOrderPrint() { + if n != nil { + n.Left.InOrderPrint() + fmt.Print(n.Key, " ") + n.Right.InOrderPrint() + } +} + +type BinaryTree2 struct { + Root *BinaryNode2 +} + +func (t *BinaryTree2) Insert(key int) *BinaryTree2 { + if t.Root == nil { + t.Root = &BinaryNode2{Key: key} + } else { + t.Root.Insert(key) + } + return t +} + +func (t *BinaryTree2) Delete(key int) *BinaryTree2 { + if t.Root != nil { + t.Root = t.Root.Delete(key) + } + return t +} + +func (t *BinaryTree2) InOrderPrint() { + t.Root.InOrderPrint() +} diff --git a/binaryTreeInsertPrint.go b/binaryTreeInsertPrint.go new file mode 100644 index 0000000..84e8b36 --- /dev/null +++ b/binaryTreeInsertPrint.go @@ -0,0 +1,61 @@ +package main + +import "fmt" + +type BinaryNode struct { + Key int + Left *BinaryNode + Right *BinaryNode +} + +type BinaryTree struct { + Root *BinaryNode +} + +// Insert will add a node to the tree +func (t *BinaryTree) Insert(key int) { + if t.Root == nil { + t.Root = &BinaryNode{Key: key} + } else { + t.Root.Insert(key) + } +} + +// Insert a node +func (n *BinaryNode) Insert(key int) { + if n.Key < key { + // move right + if n.Right == nil { + n.Right = &BinaryNode{Key: key} + } else { + n.Right.Insert(key) + } + } else if n.Key > key { + // move left + if n.Left == nil { + n.Left = &BinaryNode{Key: key} + } else { + n.Left.Insert(key) + } + } +} + +// InOrderPrint prints the tree in order +func (t *BinaryTree) InOrderPrint() { + if t.Root != nil { + t.Root.InOrderPrint() + } +} + +// InOrderPrint returns the tree in order +func (n *BinaryNode) InOrderPrint() { + if n.Left != nil { + n.Left.InOrderPrint() + } + + fmt.Printf("%v ", n.Key) + + if n.Right != nil { + n.Right.InOrderPrint() + } +} diff --git a/circularLinkedList.go b/circularLinkedList.go new file mode 100644 index 0000000..c3f4671 --- /dev/null +++ b/circularLinkedList.go @@ -0,0 +1,46 @@ +package main + +import "fmt" + +type CircularNode struct { + Value int + Next *CircularNode +} + +// Кольцевой список +type CircularList struct { + Head *CircularNode + Tail *CircularNode +} + +func (cl *CircularList) Add(value int) { + node := &CircularNode{value, nil} + + // Для пустого списка + if cl.Head == nil { + cl.Head = node + } else { + cl.Tail.Next = node + } + + cl.Tail = node + cl.Tail.Next = cl.Head // Ссылка на первый элемент для формирования кольца +} + +func (cl *CircularList) Print() { + if cl.Head != nil { + node := cl.Head + + for { + fmt.Print(node.Value, " ") + node = node.Next + + // Цикл прекращается после прохода по всему кольцу + if node == cl.Head { + break + } + } + + fmt.Println() + } +} diff --git a/doublyLinkedList.go b/doublyLinkedList.go new file mode 100644 index 0000000..162d8ca --- /dev/null +++ b/doublyLinkedList.go @@ -0,0 +1,36 @@ +package main + +import "fmt" + +type Node struct { + value int + next *Node + prev *Node +} + +type DoublyLinkedList struct { + head *Node + tail *Node +} + +func (list *DoublyLinkedList) addNode(value int) { + node := &Node{value: value} + + if list.head == nil { + list.head = node + list.tail = node + } else { + node.prev = list.tail + list.tail.next = node + list.tail = node + } +} + +func (list *DoublyLinkedList) printList() { + node := list.head + + for node != nil { + fmt.Println(node.value) + node = node.next + } +} diff --git a/graphList.go b/graphList.go new file mode 100644 index 0000000..4608d7a --- /dev/null +++ b/graphList.go @@ -0,0 +1,26 @@ +package main + +import "fmt" + +type GraphNode struct { + Name string + Children []*GraphNode +} + +func NewNode(name string) *GraphNode { + return &GraphNode{ + Name: name, + } +} + +func (n *GraphNode) AddChild(name string) { + child := NewNode(name) + n.Children = append(n.Children, child) +} + +func (n *GraphNode) Print() { + fmt.Println(n.Name) + for _, child := range n.Children { + fmt.Println(" -> ", child.Name) + } +} diff --git a/graphWidth.go b/graphWidth.go new file mode 100644 index 0000000..4ea7a3f --- /dev/null +++ b/graphWidth.go @@ -0,0 +1,22 @@ +package main + +type GraphNodeWidth struct { + Value string + Visited bool + Edges []*GraphNodeWidth +} + +func BFS(start *GraphNodeWidth, f func(*GraphNodeWidth)) { + queue := []*GraphNodeWidth{start} + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + node.Visited = true + f(node) + for _, n := range node.Edges { + if !n.Visited { + queue = append(queue, n) + } + } + } +} diff --git a/hashTableChains.go b/hashTableChains.go new file mode 100644 index 0000000..7ae7c24 --- /dev/null +++ b/hashTableChains.go @@ -0,0 +1,89 @@ +package main + +const ArraySize2 = 7 + +// HashTable structure +type HashTable2 struct { + array [ArraySize2]*bucket2 +} + +// bucket structure +type bucket2 struct { + key string + value int + next *bucket2 +} + +// Insert will take in a key and will add the item to the hash table array. +func (h *HashTable2) Insert(key string, value int) { + index := hash(key) + h.array[index].insert(key, value) +} + +// Search will take in a key and RETURN true if that key is stored in the hash table. +func (h *HashTable2) Search(key string) bool { + index := hash(key) + return h.array[index].search(key) +} + +// Delete will take in a key and DELETE it from the hash table. +func (h *HashTable2) Delete(key string) { + index := hash(key) + h.array[index].delete(key) +} + +// insert will take in a key and add it to the bucket. +func (b *bucket2) insert(k string, v int) { + if b.search(k) { + b.value = v + } else { + newBucket := &bucket2{k, v, nil} + newBucket.next = b + *b = *newBucket + } +} + +// search will take in a key and return true if it's in the bucket. +func (b *bucket2) search(k string) bool { + if b == nil { + return false + } + if b.key == k { + return true + } + + return b.next.search(k) +} + +// delete will take in a key and delete the corresponding node in the bucket. +func (b *bucket2) delete(k string) { + if b.key == k { + b = b.next + return + } + prevB := b + for b != nil && b.key != k { + prevB = b + b = b.next + } + if b != nil { + prevB.next = b.next + } +} + +// hash is the basic hashing function. +func hash2(key string) int { + sum := 0 + for _, v := range key { + sum += int(v) + } + return sum % ArraySize2 +} + +func Init() *HashTable2 { + result := &HashTable2{} + for i := range result.array { + result.array[i] = &bucket2{} + } + return result +} diff --git a/hashTableOpen.go b/hashTableOpen.go new file mode 100644 index 0000000..382503e --- /dev/null +++ b/hashTableOpen.go @@ -0,0 +1,60 @@ +package main + +const ArraySize = 7 + +// HashTable structure +type HashTable struct { + array [ArraySize]*bucket +} + +// bucket structure +type bucket struct { + key string + value int + next *bucket +} + +// Insert will take in a key and will add the item to the hash table array. +func (h *HashTable) Insert(key string, value int) { + index := hash(key) + h.array[index] = &bucket{key, value, h.array[index]} +} + +// Search will take in a key and RETURN true if that key is stored in the hash table. +func (h *HashTable) Search(key string) bool { + index := hash(key) + b := h.array[index] + for b != nil { + if b.key == key { + return true + } + b = b.next + } + return false +} + +// Delete will take in a key and DELETE it from the hash table. +func (h *HashTable) Delete(key string) { + index := hash(key) + b := h.array[index] + if b.key == key { + h.array[index] = b.next + return + } + for b.next != nil { + if b.next.key == key { + b.next = b.next.next + return + } + b = b.next + } +} + +// hash is the basic hashing function. +func hash(key string) int { + sum := 0 + for _, v := range key { + sum += int(v) + } + return sum % ArraySize +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..11d9cab --- /dev/null +++ b/main.go @@ -0,0 +1,89 @@ +package main + +import "fmt" + +func main() { + list := []int{5, 4, 0, 9, 7, 1, 3, 2, 4} + fmt.Printf("Список до сортировки - %d\n", list) + //sortedList := BubbleSort(list) + //sortedList := MergeSort(list) + sortedList := QuickSort(list) + fmt.Printf("Список после сортировки - %d", sortedList) + +} + +func BubbleSort(list []int) []int { + for i := 0; i < len(list); i++ { + for j := 0; j < len(list)-i-1; j++ { + if list[j] > list[j+1] { + temp := list[j] + list[j] = list[j+1] + list[j+1] = temp + } + } + } + return list +} + +func MergeSort(items []int) []int { + if len(items) < 2 { + return items + } + + middle := len(items) / 2 + left := MergeSort(items[:middle]) + right := MergeSort(items[middle:]) + return Merge(left, right) +} + +func Merge(left, right []int) []int { + var result []int + i := 0 + j := 0 + + for i < len(left) && j < len(right) { + if left[i] < right[j] { + result = append(result, left[i]) + i++ + } else { + result = append(result, right[j]) + j++ + } + } + + for ; i < len(left); i++ { + result = append(result, left[i]) + } + + for ; j < len(right); j++ { + result = append(result, right[j]) + } + + return result +} + +func QuickSort(arr []int) []int { + if len(arr) <= 1 { + return arr + } + + pivot := arr[len(arr)/2] + left := make([]int, 0) + middle := make([]int, 0) + right := make([]int, 0) + + for _, item := range arr { + if item < pivot { + left = append(left, item) + } else if item == pivot { + middle = append(middle, item) + } else { + right = append(right, item) + } + } + + return append( + append(QuickSort(left), middle...), + QuickSort(right)..., + ) +}