Repository: dreddsa5dies/algorithm Branch: master Commit: 9743ed7b643a Files: 46 Total size: 31.9 KB Directory structure: gitextract_txto4r26/ ├── BFS/ │ ├── README.md │ └── bfs.go ├── BST/ │ ├── README.md │ └── bst.go ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── README.md ├── binarySearch/ │ ├── README.md │ └── binarySearch.go ├── bubbleSort/ │ ├── README.md │ └── bubbleSort.go ├── bubleSortV2/ │ ├── README.md │ └── bubleSortV2.go ├── countingSort/ │ ├── README.md │ └── countingSort.go ├── go.mod ├── go.sum ├── heapSort/ │ ├── README.md │ └── heapSort.go ├── insertionSort/ │ ├── README.md │ └── insertionSort.go ├── insertionSortImpruving/ │ └── insertionSortImpruving.go ├── interpolationSearch/ │ ├── README.md │ └── interSearch.go ├── linearSearch/ │ ├── README.md │ └── linearSearch.go ├── mergeSort/ │ ├── README.md │ └── mergeSort.go ├── queue/ │ ├── README.md │ └── queue.go ├── quickSort/ │ ├── README.md │ └── quickSort.go ├── radixSort/ │ ├── README.md │ └── radixSort.go ├── selectionSort/ │ ├── README.md │ └── selectionSort.go ├── shellSort/ │ ├── README.md │ └── shellSort.go ├── shellSortUpgrade/ │ └── shellSortGap.go ├── stack/ │ ├── README.md │ └── stack.go └── util/ ├── queue/ │ └── queue.go ├── randomInt.go └── stack/ └── stack.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: BFS/README.md ================================================ Поиск в ширину (англ. breadth-first search, BFS) — метод обхода графа и поиска пути в графе ================================================ FILE: BFS/bfs.go ================================================ package main import "fmt" var nodes = map[int][]int{ 1: []int{2, 3, 4}, 2: []int{1, 5, 6}, 3: []int{1}, 4: []int{1, 7, 8}, 5: []int{2, 9, 10}, 6: []int{2}, 7: []int{4, 11, 12}, 8: []int{4}, 9: []int{5}, 10: []int{5}, 11: []int{7}, 12: []int{7}, } func main() { visited := []int{} bfs(1, nodes, func(node int) { visited = append(visited, node) }) fmt.Println(visited) } func bfs(start int, nodes map[int][]int, fn func(int)) { frontier := []int{start} visited := map[int]bool{} next := []int{} for 0 < len(frontier) { next = []int{} for _, node := range frontier { visited[node] = true fn(node) for _, n := range bfsFrontier(node, nodes, visited) { next = append(next, n) } } frontier = next } } func bfsFrontier(node int, nodes map[int][]int, visited map[int]bool) []int { next := []int{} iter := func(n int) bool { _, ok := visited[n]; return !ok } for _, n := range nodes[node] { if iter(n) { next = append(next, n) } } return next } ================================================ FILE: BST/README.md ================================================ Двоичное дерево поиска (англ. binary search tree, BST) — это двоичное дерево, для которого выполняются следующие дополнительные условия (свойства дерева поиска): * Оба поддерева — левое и правое — являются двоичными деревьями поиска. * У всех узлов левого поддерева произвольного узла X значения ключей данных меньше, нежели значение ключа данных самого узла X. * У всех узлов правого поддерева произвольного узла X значения ключей данных больше либо равны, нежели значение ключа данных самого узла X. ![IMAGE](/img/bst.png) Binary Search Tree ADT Operations: * Insert(k): вставка элемента k в дерево. * Delete(k): удаление элемента k. * Search(k): поиск значения элемента k в структуре, есть он или нет. * FindMax(): поиск максимального значения. * FindMin(): поиск минимального значения. ================================================ FILE: BST/bst.go ================================================ package main import "fmt" func main() { tree := New() fmt.Println("Insert 15 1 2") tree.Insert(15) tree.Insert(1) tree.Insert(2) fmt.Println("Size: ", tree.Size()) fmt.Println("Show: ") tree.Show() fmt.Println("Insert 3 1 3") tree.Insert(3) tree.Insert(1) tree.Insert(3) fmt.Println("Size: ", tree.Size()) fmt.Println("Show: ") tree.Show() fmt.Println("Search 4: ", tree.Search(4)) fmt.Println("Search 3: ", tree.Search(3)) fmt.Println("Insert 14 17 31") tree.Insert(14) tree.Insert(17) tree.Insert(31) fmt.Println("Size: ", tree.Size()) fmt.Println("Show: ") tree.Show() fmt.Println("Min element: ") tree.FindMin() fmt.Println("Max element: ") tree.FindMax() fmt.Println("Delete 31: ", tree.Delete(31)) fmt.Println("Delete 5: ", tree.Delete(5)) fmt.Println("Delete 5: ", tree.Delete(1)) fmt.Println("Size: ", tree.Size()) fmt.Println("Show: ") tree.Show() fmt.Println("Min element: ") tree.FindMin() fmt.Println("Max element: ") tree.FindMax() } // Node is a representation of a single node in tree. (recursive ADT) type Node struct { key int left *Node right *Node } // Bst is a struct of a nodes in tree. type Bst struct { root *Node size int } /* Binary Search Tree ADT Operations * + Insert(k): вставка элемента k в дерево. * + Delete(k): удаление элемента k. * + Search(k): поиск значения элемента k в структуре, есть он или нет. * + FindMax(): поиск максимального значения. * + FindMin(): поиск минимального значения. * + Show & Size(): печать дерева и размер. */ // New - Construtor BST func New() *Bst { return &Bst{nil, 0} } // Insert elements in tree func (tree *Bst) Insert(value int) { if tree.root == nil { tree.root = &Node{value, nil, nil} } tree.size++ tree.root.insert(&Node{value, nil, nil}) } // insert is a recursive method for node insertion func (root *Node) insert(newNode *Node) { //if data exists, skip if root.key == newNode.key { return } // to right-subtree if root.key < newNode.key { if root.right == nil { root.right = newNode } else { root.right.insert(newNode) } } else { if root.left == nil { root.left = newNode } else { root.left.insert(newNode) } } } // Size - return size tree func (tree *Bst) Size() int { return tree.size } // Search element on tree func (tree *Bst) Search(value int) bool { tree.size-- return searchElement(tree.root, value) } // search element func searchElement(root *Node, value int) bool { if root != nil { if value == root.key { return true } else if value > root.key { return searchElement(root.right, value) } else { return searchElement(root.left, value) } } return false } // Show the tree (Print the tree in-order) func (tree *Bst) Show() { printNode(tree.root) } // Print the tree in-order // Traverse the left sub-tree, root, right sub-tree func printNode(root *Node) { if root != nil { printNode(root.left) fmt.Println(root.key) printNode(root.right) } } // FindMin - print min element tree func (tree *Bst) FindMin() { fmt.Println(minValue(tree.root)) } func minValue(root *Node) int { if root != nil { if root.left == nil { return root.key } return minValue(root.left) } return root.key } // FindMax - print max element tree func (tree *Bst) FindMax() { fmt.Println(maxValue(tree.root)) } func maxValue(root *Node) int { if root != nil { if root.right == nil { return root.key } return maxValue(root.right) } return root.key } // Delete element tree func (tree *Bst) Delete(value int) bool { if !tree.Search(value) || tree.root == nil { return false } if tree.root.key == value { tempRoot := &Node{0, nil, nil} tempRoot.left = tree.root r := del(tree.root, tempRoot, value) tree.root = tempRoot.left return r } return del(tree.root.left, tree.root, value) || del(tree.root.right, tree.root, value) } func del(root *Node, parent *Node, value int) bool { switch { case root.key == value: if root.left != nil && root.right != nil { root.key = minValue(root.right) return del(root.right, root, root.key) } link(parent, root) return true case root.key > value: if root.left == nil { return false } return del(root.left, root, value) case root.key < value: if root.right == nil { return false } return del(root.right, root, value) } return false } func link(parent *Node, root *Node) { if parent.left == root { if root.left != nil { parent.left = root.left } else { parent.left = root.right } } else if parent.right == root { if root.left != nil { parent.right = root.left } else { parent.right = root.right } } } ================================================ FILE: CODE_OF_CONDUCT.md ================================================ ## Code of conduct Welcomes any kind of contribution, please follow the [how to write GO code](https://golang.org/doc/code.html) ================================================ FILE: CONTRIBUTING.md ================================================ ## Contribute Welcomes any kind of contribution, please follow the next steps: - Fork the project on github.com. - Create a new branch. - Commit changes to the new branch. - Send a pull request. ================================================ FILE: ISSUE_TEMPLATE.md ================================================ ### Issue and Steps to Reproduce ### Versions or filename ### Screenshots #### Expected #### Actual ### Additional Details * Installed packages: ================================================ FILE: LICENSE.md ================================================ Copyright 2018 Viktor Solovev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.` ================================================ FILE: README.md ================================================ [![Go Report Card](https://goreportcard.com/badge/github.com/dreddsa5dies/algorithm)](https://goreportcard.com/report/github.com/dreddsa5dies/algorithm) ![License](https://img.shields.io/badge/License-MIT-blue.svg) ## The repository algorithms implemented on the Go: ### Sort: * [Sort by simple exchange, bubble sort (Сортировка простыми обменами, сортиро́вка пузырько́м)](https://github.com/dreddsa5dies/algorithm/tree/master/bubbleSort) * [Cocktail sort (Сортировка перемешиванием, или Шейкерная сортировка, или двунаправленная)](https://github.com/dreddsa5dies/algorithm/tree/master/bubleSortV2) * [Shell Sort (Сортировка Шелла)](https://github.com/dreddsa5dies/algorithm/tree/master/shellSort) * [Insertion sort (Сортировка вставками)](https://github.com/dreddsa5dies/algorithm/tree/master/insertionSort) * [Fast sorting, sorting Hoare (Quicksort) (Быстрая сортировка, сортировка Хоара)](https://github.com/dreddsa5dies/algorithm/tree/master/quickSort) * [Selection sort (Сортировка выбором)](https://github.com/dreddsa5dies/algorithm/tree/master/selectionSort) * [Heap sort (Пирамидальная сортировка, «Сортировка кучей»)](https://github.com/dreddsa5dies/algorithm/tree/master/heapSort) * [Merge sort (Сортировка слиянием)](https://github.com/dreddsa5dies/algorithm/tree/master/mergeSort) * [Radix sort (Поразрядная сортировка)](https://github.com/dreddsa5dies/algorithm/tree/master/radixSort) * [Counting sort (Сортировка подсчётом)](https://github.com/dreddsa5dies/algorithm/tree/master/countingSort) ### Search: * [Binary search (Бинарный поиск)](https://github.com/dreddsa5dies/algorithm/tree/master/binarySearch) * [Breadth-first search, BFS (Поиск в ширину (англ. breadth-first search, BFS) — метод обхода графа и поиска пути в графе)](https://github.com/dreddsa5dies/algorithm/tree/master/BFS) * [Linear search (Линейный, последовательный поиск)](https://github.com/dreddsa5dies/algorithm/tree/master/linearSearch) * [Interpolation search (Интерполяционный, интерполирующий поиск)](https://github.com/dreddsa5dies/algorithm/tree/master/interpolationSearch) ### ADT: * [Stack (абстрактный тип данных, представляющий собой список элементов, организованных по принципу LIFO)](https://github.com/dreddsa5dies/algorithm/tree/master/stack) * [Queue (абстрактный тип данных, представляющий собой список элементов, организованных по принципу FIFO)](https://github.com/dreddsa5dies/algorithm/tree/master/queue) * [Binary search tree, BST (Двоичное дерево поиска)](https://github.com/dreddsa5dies/algorithm/tree/master/BST) * [HEAP (Ку́ча - динамически распределяемая память приложения)](https://golang.org/pkg/container/heap/) * [Doubly linked list (Двунаправленный список)](https://golang.org/pkg/container/list/) * [Circular lists (Круговой связанный список)](https://golang.org/pkg/container/ring/) ## The code contains comments in Russian ## License This project is licensed under MIT license. Please read the [LICENSE](https://github.com/dreddsa5dies/algorithm/tree/master/LICENSE.md) file. ## Contribute Welcomes any kind of contribution. Please read the [CONTRIBUTING](https://github.com/dreddsa5dies/algorithm/tree/master/CONTRIBUTING.md), [ISSUE TEMPLATE](https://github.com/dreddsa5dies/algorithm/tree/master/ISSUE_TEMPLATE.md) and [CODE_OF_CONDUCT](https://github.com/dreddsa5dies/algorithm/tree/master/CODE_OF_CONDUCT.md) file. [![Anurag's github stats](https://github-readme-stats.vercel.app/api?username=dreddsa5dies)](https://github.com/anuraghazra/github-readme-stats) ================================================ FILE: binarySearch/README.md ================================================ Двоичный (бинарный) поиск (также известен как метод деления пополам и дихотомия) — классический алгоритм поиска элемента в отсортированном массиве (векторе), использующий дробление массива на половины. ================================================ FILE: binarySearch/binarySearch.go ================================================ package main import ( "fmt" "sort" "os" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int sort.Ints(s1) fmt.Printf("Sorted list:\t%v\n", s1) a := util.Integer("Inter number") binSearch(s1, a) } func binSearch(list []int, item int) { low := 0 high := len(list) - 1 for low <= high { mid := (low + high) / 2 guess := list[mid] if guess == item { fmt.Printf("Position:\t%v\n", mid) os.Exit(0) } if guess > item { high = mid - 1 } else { low = mid + 1 } } fmt.Println("Not found") } ================================================ FILE: bubbleSort/README.md ================================================ Сортировка простыми обменами, сортиро́вка пузырько́м (англ. bubble sort) — простой алгоритм сортировки. Для понимания и реализации этот алгоритм — простейший, но эффективен он лишь для небольших массивов. Сложность алгоритма: O (n^{2}). Алгоритм считается учебным и практически не применяется вне учебной литературы, вместо него на практике применяются более эффективные алгоритмы сортировки. В то же время метод сортировки обменами лежит в основе некоторых более совершенных алгоритмов, таких как шейкерная сортировка, пирамидальная сортировка и быстрая сортировка. ================================================ FILE: bubbleSort/bubbleSort.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { // sort on the right s1 := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") length := len(s1) for i := 0; i < (length - 1); i++ { for j := 0; j < ((length - 1) - i); j++ { if s1[j] > s1[j+1] { s1[j], s1[j+1] = s1[j+1], s1[j] } } fmt.Printf("Sorting ...:\t%v\n", s1) } fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } ================================================ FILE: bubleSortV2/README.md ================================================ Сортировка перемешиванием, или Шейкерная сортировка, или двунаправленная (англ. Cocktail sort) — разновидность пузырьковой сортировки. ================================================ FILE: bubleSortV2/bubleSortV2.go ================================================ // Cocktail sort package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { // sort on the left s1 := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") length := len(s1) for i := 0; i < (length - 1); i++ { for j := (length - 1); j > i; j-- { if s1[j] < s1[j-1] { s1[j], s1[j-1] = s1[j-1], s1[j] } } fmt.Printf("Sorting ...:\t%v\n", s1) } fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } ================================================ FILE: countingSort/README.md ================================================ Сортировка подсчётом (англ. counting sort; сортировка посредством подсчёта англ. sorting by counting) — алгоритм сортировки, в котором используется диапазон чисел сортируемого массива (списка) для подсчёта совпадающих элементов. Применение сортировки подсчётом целесообразно лишь тогда, когда сортируемые числа имеют (или их можно отобразить в) диапазон возможных значений, который достаточно мал по сравнению с сортируемым множеством, например, миллион натуральных чисел меньших 1000. ================================================ FILE: countingSort/countingSort.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { arr := util.RandomInt() // срез int fmt.Println("Unsorted List:", arr) k := getK(arr) tmpArr := make([]int, k) for i := 0; i < len(arr); i++ { tmpArr[arr[i]]++ } for i, j := 0, 0; i < k; i++ { for { if tmpArr[i] > 0 { arr[j] = i j++ tmpArr[i]-- continue } break } } fmt.Println("Sorted List: ", arr) } func getK(arr []int) int { if len(arr) == 0 { return 1 } k := arr[0] for _, v := range arr { if v > k { k = v } } return k + 1 } ================================================ FILE: go.mod ================================================ module algorithm go 1.17 require github.com/dreddsa5dies/algorithm v0.0.0-20210807072651-68e310fc4e7c ================================================ FILE: go.sum ================================================ github.com/dreddsa5dies/algorithm v0.0.0-20210807072651-68e310fc4e7c h1:+IsVypOBnNZpGvjI4ryPEU0ybiMiAxtDLJLnIBjCB+c= github.com/dreddsa5dies/algorithm v0.0.0-20210807072651-68e310fc4e7c/go.mod h1:GGavcA9TE70M+HEmeEx2UTTitaMvUbwQ4r1apSyHln0= ================================================ FILE: heapSort/README.md ================================================ Пирамидальная сортировка (англ. Heapsort, «Сортировка кучей») — алгоритм сортировки, работающий в худшем, в среднем и в лучшем случае (то есть гарантированно) за Θ(n log n) операций при сортировке n элементов. Количество применяемой служебной памяти не зависит от размера массива (то есть, O(1)). ================================================ FILE: heapSort/heapSort.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) var maxChild int func main() { s1 := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") i := 0 tmp := 0 for i = len(s1)/2 - 1; i >= 0; i-- { s1 = heapSort(s1, i, len(s1)) } for i = len(s1) - 1; i >= 1; i-- { tmp = s1[0] s1[0] = s1[i] s1[i] = tmp s1 = heapSort(s1, 0, i) } fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } func heapSort(s1 []int, i int, s1Len int) []int { done := false tmp := 0 maxChild := 0 for (i*2+1 < s1Len) && (!done) { if i*2+1 == s1Len-1 { maxChild = i*2 + 1 } else if s1[i*2+1] > s1[i*2+2] { maxChild = i*2 + 1 } else { maxChild = i*2 + 2 } if s1[i] < s1[maxChild] { tmp = s1[i] s1[i] = s1[maxChild] s1[maxChild] = tmp i = maxChild } else { done = true } fmt.Printf("Sorting ...:\t%v\n", s1) } return s1 } ================================================ FILE: insertionSort/README.md ================================================ Сортировка вставками (англ. Insertion sort) — алгоритм сортировки, в котором элементы входной последовательности просматриваются по одному, и каждый новый поступивший элемент размещается в подходящее место среди ранее упорядоченных элементов[1]. Вычислительная сложность — O(n^{2}). ================================================ FILE: insertionSort/insertionSort.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") for i := 1; i < len(s1); i++ { for j := i; j != 0 && s1[j] < s1[j-1]; j-- { s1[j-1], s1[j] = s1[j], s1[j-1] } fmt.Printf("Sorting ...:\t%v\n", s1) } fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } ================================================ FILE: insertionSortImpruving/insertionSortImpruving.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") for i := 1; i < len(s1); i++ { value := s1[i] for j := i; j != 0 && value < s1[j-1]; s1[j] = value { s1[j] = s1[j-1] j-- } fmt.Printf("Sorting ...:\t%v\n", s1) } fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } ================================================ FILE: interpolationSearch/README.md ================================================ Интерполяционный поиск (интерполирующий поиск) основан на принципе поиска в телефонной книге или, например, в словаре. Вместо сравнения каждого элемента с искомым, как при линейном поиске, данный алгоритм производит предсказание местонахождения элемента: поиск происходит подобно двоичному поиску, но вместо деления области поиска на две части, интерполирующий поиск производит оценку новой области поиска по расстоянию между ключом и текущим значением элемента. Другими словами, бинарный поиск учитывает лишь знак разности между ключом и текущим значением, а интерполирующий ещё учитывает и модуль этой разности и по данному значению производит предсказание позиции следующего элемента для проверки. В среднем интерполирующий поиск производит log(log(N)) операций, где N есть число элементов, среди которых производится поиск. Число необходимых операций зависит от равномерности распределения значений среди элементов. В плохом случае (например, когда значения элементов экспоненциально возрастают) интерполяционный поиск может потребовать до O(N) операций. ================================================ FILE: interpolationSearch/interSearch.go ================================================ package main import ( "fmt" "os" "sort" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int sort.Ints(s1) fmt.Printf("Sorted list:\t%v\n", s1) a := util.Integer("Inter number") interSearch(s1, a) } func interSearch(sortedArray []int, toFind int) { var mid int low := 0 high := len(sortedArray) - 1 for sortedArray[low] < toFind && sortedArray[high] > toFind { mid = low + ((toFind-sortedArray[low])*(high-low))/(sortedArray[high]-sortedArray[low]) if sortedArray[mid] < toFind { low = mid + 1 } else if sortedArray[mid] > toFind { high = mid - 1 } else { fmt.Println("Found: ", mid) os.Exit(0) } } if sortedArray[low] == toFind { fmt.Println("Found: ", low) os.Exit(0) } else if sortedArray[high] == toFind { fmt.Println("Found: ", high) os.Exit(0) } else { fmt.Println("Not found") } } ================================================ FILE: linearSearch/README.md ================================================ Линейный, последовательный поиск — алгоритм нахождения заданного значения произвольной функции на некотором отрезке. Данный алгоритм является простейшим алгоритмом поиска и, в отличие, например, от двоичного поиска, не накладывает никаких ограничений на функцию и имеет простейшую реализацию. Поиск значения функции осуществляется простым сравнением очередного рассматриваемого значения (как правило, поиск происходит слева направо, то есть от меньших значений аргумента к большим) и, если значения совпадают (с той или иной точностью), то поиск считается завершённым. ================================================ FILE: linearSearch/linearSearch.go ================================================ package main import ( "fmt" "os" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int fmt.Printf("List:\t%v\n", s1) a := util.Integer("Inter number") linearSearch(s1, a) } func linearSearch(list []int, item int) { for index, value := range list { if value == item { fmt.Printf("Position:\t%v\n", index) os.Exit(0) } } fmt.Println("Not found") } ================================================ FILE: mergeSort/README.md ================================================ Сортировка слиянием (англ. merge sort) — алгоритм сортировки, который упорядочивает списки (или другие структуры данных, доступ к элементам которых можно получать только последовательно, например — потоки) в определённом порядке. Эта сортировка — хороший пример использования принципа «разделяй и властвуй». Сначала задача разбивается на несколько подзадач меньшего размера. Затем эти задачи решаются с помощью рекурсивного вызова или непосредственно, если их размер достаточно мал. Наконец, их решения комбинируются, и получается решение исходной задачи. ================================================ FILE: mergeSort/mergeSort.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { noSort := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", noSort) sorted := sort(noSort) fmt.Println("") fmt.Printf("Sorted list:\t%v\n", sorted) } func sort(m []int) []int { if len(m) <= 1 { return m } mid := len(m) / 2 left := m[:mid] right := m[mid:] left = sort(left) right = sort(right) return merge(left, right) } func merge(left, right []int) []int { var result []int for len(left) > 0 || len(right) > 0 { if len(left) > 0 && len(right) > 0 { if left[0] <= right[0] { result = append(result, left[0]) fmt.Printf("Sorting:\t%v\n", result) left = left[1:] } else { result = append(result, right[0]) fmt.Printf("Sorting:\t%v\n", result) right = right[1:] } } else if len(left) > 0 { result = append(result, left[0]) fmt.Printf("Sorting:\t%v\n", result) left = left[1:] } else if len(right) > 0 { result = append(result, right[0]) fmt.Printf("Sorting:\t%v\n", result) right = right[1:] } } return result } ================================================ FILE: queue/README.md ================================================ О́чередь — абстрактный тип данных с дисциплиной доступа к элементам «первый пришёл — первый вышел» (FIFO, англ. first in, first out). Добавление элемента (принято обозначать словом enqueue — поставить в очередь) возможно лишь в конец очереди, выборка — только из начала очереди (что принято называть словом dequeue — убрать из очереди), при этом выбранный элемент из очереди удаляется. ![IMAGE](/img/Queue.png) Queue ADT Operations: * Enqueue(): Добавить новый элемент в конец очереди. * Dequeue(): Удаление элемента из передней части очереди и возврат его значения. * Peek(): Вернуть значение элемента в начале очереди. * Len(): Возвращает количество элементов внутри очереди. ================================================ FILE: queue/queue.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" "github.com/dreddsa5dies/algorithm/util/queue" ) func main() { list := util.RandomInt() // срез int fmt.Printf("List:\t%v\n", list) q := queue.New() fmt.Println("Len Queue: ", q.Len()) fmt.Println("Enqueue:") for i := 0; i < len(list); i++ { fmt.Print(list[i], " ") q.Enqueue(list[i]) } fmt.Println("") fmt.Println("Len Queue: ", q.Len()) fmt.Println("Peek Queue: ", q.Peek()) fmt.Println("Dequeue:") for q.Len() != 0 { val := q.Dequeue() fmt.Print(val, " ") } } ================================================ FILE: quickSort/README.md ================================================ Быстрая сортировка, сортировка Хоара (англ. quicksort), часто называемая qsort (по имени в стандартной библиотеке языка Си) — широко известный алгоритм сортировки, разработанный английским информатиком Чарльзом Хоаром во время его работы в МГУ в 1960 году. Один из самых быстрых известных универсальных алгоритмов сортировки массивов: в среднем O(n\log n) обменов при упорядочении n элементов; из-за наличия ряда недостатков на практике обычно используется с некоторыми доработками. ================================================ FILE: quickSort/quickSort.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) var index, start, end int func main() { s1 := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") sort(s1, 0, len(s1)-1) fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } func sort(s1 []int, start, end int) { if start >= end { return } pivot := s1[start] i := start + 1 for j := start; j <= end; j++ { if pivot > s1[j] { s1[i], s1[j] = s1[j], s1[i] i++ } fmt.Printf("Sorting ...:\t%v\n", s1) } s1[start], s1[i-1] = s1[i-1], s1[start] sort(s1, start, i-2) sort(s1, i, end) } ================================================ FILE: radixSort/README.md ================================================ Поразрядная сортировка (англ. radix sort) — алгоритм сортировки, который выполняется за линейное время. ================================================ FILE: radixSort/radixSort.go ================================================ // Thanks https://austingwalters.com/radix-sort-in-go/ package main import ( "fmt" "strconv" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int fmt.Println("Unsorted List:", s1) sortedList := radixSort(s1) fmt.Println("Sorted List:", sortedList) } // Finds the largest number in an array func findLargestNum(array []int) int { largestNum := 0 for i := 0; i < len(array); i++ { if array[i] > largestNum { largestNum = array[i] } } return largestNum } // Radix Sort func radixSort(array []int) []int { fmt.Println("Running Radix Sort on Unsorted List") // Base 10 is used largestNum := findLargestNum(array) size := len(array) significantDigit := 1 semiSorted := make([]int, size, size) // Loop until we reach the largest significant digit for largestNum/significantDigit > 0 { fmt.Println("\tSorting: "+strconv.Itoa(significantDigit)+"'s place", array) bucket := [10]int{0} // Counts the number of "keys" or digits that will go into each bucket for i := 0; i < size; i++ { bucket[(array[i]/significantDigit)%10]++ } // Add the count of the previous buckets // Acquires the indexes after the end of each bucket location in the array // Works similar to the count sort algorithm for i := 1; i < 10; i++ { bucket[i] += bucket[i-1] } // Use the bucket to fill a "semiSorted" array for i := size - 1; i >= 0; i-- { bucket[(array[i]/significantDigit)%10]-- semiSorted[bucket[(array[i]/significantDigit)%10]] = array[i] } // Replace the current array with the semisorted array for i := 0; i < size; i++ { array[i] = semiSorted[i] } fmt.Println("\n\tBucket: ", bucket) // Move to next significant digit significantDigit *= 10 } return array } ================================================ FILE: selectionSort/README.md ================================================ Сортировка выбором (Selection sort) — алгоритм сортировки. Может быть как устойчивый, так и неустойчивый. На массиве из n элементов имеет время выполнения в худшем, среднем и лучшем случае Θ(n2), предполагая что сравнения делаются за постоянное время. ================================================ FILE: selectionSort/selectionSort.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") for i := 0; i < len(s1); i++ { minIndex := i j := i + 1 for j < len(s1) { if s1[j] < s1[minIndex] { minIndex = j } j = j + 1 } s1[i], s1[minIndex] = s1[minIndex], s1[i] fmt.Printf("Sorting list:\t%v\n", s1) } fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } ================================================ FILE: shellSort/README.md ================================================ Сортировка Шелла (англ. Shell sort) — алгоритм сортировки, являющийся усовершенствованным вариантом сортировки вставками. Идея метода Дональда Шелла состоит в сравнении элементов, стоящих не только рядом, но и на определённом расстоянии друг от друга; иными словами — это сортировка вставками, но с предварительными «грубыми» проходами. Аналогичный метод усовершенствования «пузырьковой» сортировки называется «сортировка расчёской». ================================================ FILE: shellSort/shellSort.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") length := len(s1) gap := int(length / 2) for gap >= 1 { for i := gap; i < length; i++ { value := s1[i] for j := i; (j-gap) >= 0 && value < s1[j-gap]; s1[j] = value { s1[j] = s1[j-gap] j = j - gap fmt.Printf("Sorting ...:\t%v\n", s1) } } gap = int(gap / 2) } fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } ================================================ FILE: shellSortUpgrade/shellSortGap.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" ) func main() { s1 := util.RandomInt() // срез int shellSort(s1) } func shellSort(s1 []int) { fmt.Printf("Unsorted list:\t%v\n", s1) fmt.Println("") length := len(s1) gap := int(length / 3) // modify gap by 3 if gap == 0 { gap = 1 } for gap >= 1 { for i := gap; i < length; i++ { value := s1[i] for j := i; (j-gap) >= 0 && value < s1[j-gap]; s1[j] = value { s1[j] = s1[j-gap] j = j - gap } } fmt.Printf("gap:\t%v\n", gap) gap = int(gap / 3) // modify gap by 3 fmt.Printf("Sorting ...:\t%v\n", s1) } fmt.Println("") fmt.Printf("Sorted list:\t%v\n", s1) } ================================================ FILE: stack/README.md ================================================ Стек (англ. stack — стопка; читается стэк) — абстрактный тип данных, представляющий собой список элементов, организованных по принципу LIFO (англ. last in — first out, «последним пришёл — первым вышел»). ![IMAGE](/img/Lifo_stack.png) Stack ADT Operations: * Push(): Добавляет новый элемент в начало стека. * Pop(): Удаление элемента из верхней части стека и возврат его значения. * Peek(): Возвращает значение элемента в верхней части стека, не удаляя его. * Len(): Возвращает количество элементов в стеке. ================================================ FILE: stack/stack.go ================================================ package main import ( "fmt" "github.com/dreddsa5dies/algorithm/util" "github.com/dreddsa5dies/algorithm/util/stack" ) func main() { list := util.RandomInt() // срез int fmt.Printf("List:\t%v\n", list) s := stack.New() fmt.Println("Len Stack: ", s.Len()) fmt.Println("Push:") for i := 0; i < len(list); i++ { fmt.Print(list[i], " ") s.Push(list[i]) } fmt.Println("") fmt.Println("Len Stack: ", s.Len()) fmt.Println("Peek Stack: ", s.Peek()) fmt.Println("Pop:") for s.Len() != 0 { val := s.Pop() fmt.Print(val, " ") } } ================================================ FILE: util/queue/queue.go ================================================ package queue type ( // Queue - Очередь представляется в качестве линейного списка, // в котором добавление/удаление элементов идет строго с соответствующих его концов. Queue struct { start, end *node length int } node struct { value interface{} next *node } ) // New - создание новой очереди func New() *Queue { return &Queue{nil, nil, 0} } // Dequeue - Удаление элемента из передней части очереди и возврат его значения. func (que *Queue) Dequeue() interface{} { if que.length == 0 { return nil } n := que.start if que.length == 1 { que.start = nil que.end = nil } else { que.start = que.start.next } que.length-- return n.value } // Enqueue - Добавить новый элемент в конец очереди. func (que *Queue) Enqueue(value interface{}) { n := &node{value, nil} if que.length == 0 { que.start = n que.end = n } else { que.end.next = n que.end = n } que.length++ } // Len - Возвращает количество элементов внутри очереди. func (que *Queue) Len() int { return que.length } // Peek - Вернуть значение элемента в начале очереди, не удаляя его func (que *Queue) Peek() interface{} { if que.length == 0 { return nil } return que.start.value } ================================================ FILE: util/randomInt.go ================================================ package util import ( "fmt" "math/rand" ) // RandomInt create random array []int, len()=20 func RandomInt() []int { list := rand.Perm(20) for i := 0; i < len(list); i++ { j := rand.Intn(i + 1) list[i], list[j] = list[j], list[i] } return list } // Integer ввод целого числа в stdin func Integer(msg string) int { fmt.Print(msg + " > ") var num int _, err := fmt.Scanf("%d", &num) if err != nil { panic("Ввод неверных данных") } return num } ================================================ FILE: util/stack/stack.go ================================================ package stack type ( // Stack - список элементов // Зачастую стек реализуется в виде однонаправленного списка // (каждый элемент в списке содержит помимо хранимой информации в стеке указатель // на следующий элемент стека). Stack struct { top *node length int } node struct { value interface{} prev *node } ) // New - создание нового стэка func New() *Stack { return &Stack{nil, 0} } // Len - возврат количества элементов в стеке func (st *Stack) Len() int { return st.length } // Peek - возврат верхнего элемента func (st *Stack) Peek() interface{} { if st.length == 0 { return nil } return st.top.value } // Pop - возврат элемента и удаление его func (st *Stack) Pop() interface{} { if st.length == 0 { return nil } n := st.top st.top = n.prev st.length-- return n.value } // Push - значение в верхней части стека func (st *Stack) Push(value interface{}) { n := &node{value, st.top} st.top = n st.length++ }