commit 58af1a12120dff920688aab3986fb4e87d38f34b Author: Mamoru777 Date: Thu May 30 11:50:30 2024 +0400 Done 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)..., + ) +}