├── .travis.yml ├── BinarySearch ├── BinarySearch.go └── BinarySearch_test.go ├── BinaryTree └── BinaryTree.go ├── BubbleSort ├── BubbleSort.go └── BubbleSort_test.go ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CircularBuffer └── CircularBuffer.go ├── CocktailSort ├── CocktailSort.go └── CocktailSort_test.go ├── CombSort ├── CombSort.go └── CombSort_test.go ├── DoublyLinkedList └── DoublyLinkedList.go ├── ExponentialSearch ├── ExponentialSearch.go └── ExponentialSearch_test.go ├── GnomeSort ├── GnomeSort.go └── GnomeSort_test.go ├── HashTable └── HashTable.go ├── InsertionSort ├── InsertionSort.go └── InsertionSort_test.go ├── InterpolationSearch ├── InterpolationSearch.go └── InterpolationSearch_test.go ├── JumpSearch ├── JumpSearch.go └── JumpSearch_test.go ├── LICENSE ├── LinearSearch ├── LinearSearch.go └── LinearSearch_test.go ├── LinkedList └── LinkedList.go ├── MergeSort ├── MergeSort.go └── MergeSort_test.go ├── NaiveStringSearch ├── NaiveStringSearch.go └── NaiveStringSearch_test.go ├── Queue(LinkedList) └── Queue.go ├── README.md ├── RabinKarp ├── RabinKarp.go └── RabinKarp_test.go ├── ReverseArray └── ReverseArray.go ├── SelectionSort ├── SelectionSort.go └── SelectionSort_test.go ├── Stack(Array) └── Stack.go ├── Stack(LinkedList) └── Stack.go ├── TernarySearch ├── TernarySearch.go └── TernarySearch_test.go ├── Trie └── Trie.go └── dsa.go /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - "1.9.x" 5 | - "1.10.x" 6 | 7 | script: 8 | cd BinarySearch && go test ./; 9 | cd ../BubbleSort && go test ./; 10 | cd ../CocktailSort && go test ./; 11 | cd ../CombSort && go test ./; 12 | cd ../ExponentialSearch && go test ./; 13 | cd ../GnomeSort && go test ./; 14 | cd ../InsertionSort && go test ./; 15 | cd ../InterpolationSearch && go test ./; 16 | cd ../JumpSearch && go test ./; 17 | cd ../LinearSearch && go test ./; 18 | cd ../MergeSort && go test ./; 19 | cd ../SelectionSort && go test ./; 20 | cd ../TernarySearch && go test ./; 21 | cd ../NaiveStringSearch && go test ./; 22 | cd ../RabinKarp && go test ./; 23 | -------------------------------------------------------------------------------- /BinarySearch/BinarySearch.go: -------------------------------------------------------------------------------- 1 | package BinarySearch 2 | 3 | func BinarySearch(array []int, number int) int { 4 | minIndex := 0 5 | maxIndex := len(array) - 1 6 | for minIndex <= maxIndex { 7 | midIndex := int((maxIndex + minIndex) / 2) 8 | midItem := array[midIndex] 9 | if number == midItem { 10 | return midIndex 11 | } 12 | if midItem < number { 13 | minIndex = midIndex + 1 14 | } else if midItem > number { 15 | maxIndex = midIndex - 1 16 | } 17 | } 18 | return -1 19 | } 20 | -------------------------------------------------------------------------------- /BinarySearch/BinarySearch_test.go: -------------------------------------------------------------------------------- 1 | package BinarySearch 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func SortArray(array []int) { 10 | for itemIndex, itemValue := range array { 11 | for itemIndex != 0 && array[itemIndex-1] > itemValue { 12 | array[itemIndex] = array[itemIndex-1] 13 | itemIndex -= 1 14 | } 15 | array[itemIndex] = itemValue 16 | } 17 | } 18 | 19 | func TestBinarySearch(t *testing.T) { 20 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 21 | array := make([]int, random.Intn(100-10)+10) 22 | for i := range array { 23 | array[i] = random.Intn(100) 24 | } 25 | SortArray(array) 26 | for _, value := range array { 27 | result := BinarySearch(array, value) 28 | if result == -1 { 29 | t.Fail() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /BinaryTree/BinaryTree.go: -------------------------------------------------------------------------------- 1 | package BinaryTree 2 | 3 | type Node struct { 4 | data int 5 | parent *Node 6 | left *Node 7 | right *Node 8 | } 9 | 10 | type BinaryTree struct { 11 | root *Node 12 | } 13 | 14 | func (tree *BinaryTree) InsertItem(i int) { 15 | if tree.root == nil { 16 | tree.root = &Node{data: i} 17 | return 18 | } 19 | currentNode := tree.root 20 | for { 21 | if i > currentNode.data { 22 | if currentNode.right == nil { 23 | currentNode.right = &Node{data: i, parent: currentNode} 24 | return 25 | } 26 | currentNode = currentNode.right 27 | } else { 28 | if currentNode.left == nil { 29 | currentNode.left = &Node{data: i, parent: currentNode} 30 | return 31 | } 32 | currentNode = currentNode.left 33 | } 34 | } 35 | } 36 | 37 | func (tree *BinaryTree) SearchItem(i int) (*Node, bool) { 38 | if tree.root == nil { 39 | return nil, false 40 | } 41 | currentNode := tree.root 42 | for currentNode != nil { 43 | if i == currentNode.data { 44 | return currentNode, true 45 | } else if i > currentNode.data { 46 | currentNode = currentNode.right 47 | } else if i < currentNode.data { 48 | currentNode = currentNode.left 49 | } 50 | } 51 | return nil, false 52 | } 53 | 54 | func (tree *BinaryTree) InorderTraversal(subtree *Node, callback func(int)) { 55 | if subtree.left != nil { 56 | tree.InorderTraversal(subtree.left, callback) 57 | } 58 | callback(subtree.data) 59 | if subtree.right != nil { 60 | tree.InorderTraversal(subtree.right, callback) 61 | } 62 | } 63 | 64 | func (tree *BinaryTree) PreorderTraversal(subtree *Node, callback func(int)) { 65 | callback(subtree.data) 66 | if subtree.left != nil { 67 | tree.PreorderTraversal(subtree.left, callback) 68 | } 69 | if subtree.right != nil { 70 | tree.PreorderTraversal(subtree.right, callback) 71 | } 72 | } 73 | 74 | func (tree *BinaryTree) PostorderTraversal(subtree *Node, callback func(int)) { 75 | if subtree.left != nil { 76 | tree.PostorderTraversal(subtree.left, callback) 77 | } 78 | if subtree.right != nil { 79 | tree.PostorderTraversal(subtree.right, callback) 80 | } 81 | callback(subtree.data) 82 | } 83 | -------------------------------------------------------------------------------- /BubbleSort/BubbleSort.go: -------------------------------------------------------------------------------- 1 | package BubbleSort 2 | 3 | func BubbleSort(array []int) { 4 | swapCount := 1 5 | for swapCount > 0 { 6 | swapCount = 0 7 | for itemIndex := 0; itemIndex < len(array)-1; itemIndex++ { 8 | if array[itemIndex] > array[itemIndex+1] { 9 | array[itemIndex], array[itemIndex+1] = array[itemIndex+1], array[itemIndex] 10 | swapCount += 1 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /BubbleSort/BubbleSort_test.go: -------------------------------------------------------------------------------- 1 | package BubbleSort 2 | 3 | import ( 4 | "math/rand" 5 | "sort" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestBubbleSort(t *testing.T) { 11 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 12 | array1 := make([]int, random.Intn(100-10)+10) 13 | for i := range array1 { 14 | array1[i] = random.Intn(100) 15 | } 16 | array2 := make(sort.IntSlice, len(array1)) 17 | copy(array2, array1) 18 | BubbleSort(array1) 19 | array2.Sort() 20 | for i := range array1 { 21 | if array1[i] != array2[i] { 22 | t.Fail() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | education, socio-economic status, nationality, personal appearance, race, 10 | religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at floyernick@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guide 2 | 3 | Hi! Thanks for the interest in the project. Here are some notes if you want to make the project better ;) 4 | 5 | #### I have a question 6 | Clearly formulate your question and create an issue. 7 | 8 | #### I have found a bug 9 | Simply create a pull request and provide a detailed description of the problem. 10 | 11 | #### I have a proposition for improvement 12 | Create an issue if you have an idea or create a pull request if you know how to solve it in a source code. 13 | 14 | #### I have made own implementation of algorithm or data structure 15 | Unfortunately, we do not accept third-party implementations. 16 | 17 | ### General notes 18 | - Make your code clean and clear. 19 | - Make sure that your code passes the tests, otherwise, it will be rejected. 20 | - Use labels to specify the type of issue or pull request. 21 | -------------------------------------------------------------------------------- /CircularBuffer/CircularBuffer.go: -------------------------------------------------------------------------------- 1 | package CircularBuffer 2 | 3 | const arraySize = 10 4 | 5 | type CircularBuffer struct { 6 | data [arraySize]int 7 | pointer int 8 | } 9 | 10 | func (b *CircularBuffer) InsertValue(i int) { 11 | if b.pointer == len(b.data) { 12 | b.pointer = 0 13 | } 14 | b.data[b.pointer] = i 15 | b.pointer += 1 16 | } 17 | 18 | func (b *CircularBuffer) GetValues() [arraySize]int { 19 | return b.data 20 | } 21 | 22 | func (b *CircularBuffer) GetValuesFromPosition(i int) ([arraySize]int, bool) { 23 | var out [arraySize]int 24 | 25 | if i >= len(out) { 26 | return out, false 27 | } 28 | 29 | for u := 0; u < len(out); u++ { 30 | if i >= len(b.data) { 31 | i = 0 32 | } 33 | out[u] = b.data[i] 34 | i += 1 35 | } 36 | return out, true 37 | } 38 | -------------------------------------------------------------------------------- /CocktailSort/CocktailSort.go: -------------------------------------------------------------------------------- 1 | package CocktailSort 2 | 3 | func CocktailSort(array []int) { 4 | swapCount := 1 5 | for swapCount > 0 { 6 | swapCount = 0 7 | for itemIndex := 0; itemIndex < len(array)-1; itemIndex++ { 8 | if array[itemIndex] > array[itemIndex+1] { 9 | array[itemIndex], array[itemIndex+1] = array[itemIndex+1], array[itemIndex] 10 | swapCount += 1 11 | } 12 | } 13 | for itemIndex := len(array) - 1; itemIndex > 0; itemIndex-- { 14 | if array[itemIndex] < array[itemIndex-1] { 15 | array[itemIndex], array[itemIndex-1] = array[itemIndex-1], array[itemIndex] 16 | swapCount += 1 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /CocktailSort/CocktailSort_test.go: -------------------------------------------------------------------------------- 1 | package CocktailSort 2 | 3 | import ( 4 | "math/rand" 5 | "sort" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestCocktailSort(t *testing.T) { 11 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 12 | array1 := make([]int, random.Intn(100-10)+10) 13 | for i := range array1 { 14 | array1[i] = random.Intn(100) 15 | } 16 | array2 := make(sort.IntSlice, len(array1)) 17 | copy(array2, array1) 18 | CocktailSort(array1) 19 | array2.Sort() 20 | for i := range array1 { 21 | if array1[i] != array2[i] { 22 | t.Fail() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CombSort/CombSort.go: -------------------------------------------------------------------------------- 1 | package CombSort 2 | 3 | func CombSort(array []int) { 4 | gapValue := len(array) 5 | swapCount := 1 6 | for gapValue >= 1 && swapCount != 0 { 7 | if gapValue != 1 { 8 | gapValue = int(float64(gapValue) / float64(1.3)) 9 | } 10 | swapCount = 0 11 | firstItem := 0 12 | secondItem := gapValue 13 | for secondItem != len(array) { 14 | if array[firstItem] > array[secondItem] { 15 | array[firstItem], array[secondItem] = array[secondItem], array[firstItem] 16 | swapCount += 1 17 | } 18 | firstItem += 1 19 | secondItem += 1 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CombSort/CombSort_test.go: -------------------------------------------------------------------------------- 1 | package CombSort 2 | 3 | import ( 4 | "math/rand" 5 | "sort" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestCombSort(t *testing.T) { 11 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 12 | array1 := make([]int, random.Intn(100-10)+10) 13 | for i := range array1 { 14 | array1[i] = random.Intn(100) 15 | } 16 | array2 := make(sort.IntSlice, len(array1)) 17 | copy(array2, array1) 18 | CombSort(array1) 19 | array2.Sort() 20 | for i := range array1 { 21 | if array1[i] != array2[i] { 22 | t.Fail() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /DoublyLinkedList/DoublyLinkedList.go: -------------------------------------------------------------------------------- 1 | package DoublyLinkedList 2 | 3 | type Node struct { 4 | data int 5 | next *Node 6 | prev *Node 7 | } 8 | 9 | type LinkedList struct { 10 | head *Node 11 | tail *Node 12 | } 13 | 14 | func (list *LinkedList) InsertFirst(i int) { 15 | data := &Node{data: i} 16 | if list.head != nil { 17 | list.head.prev = data 18 | data.next = list.head 19 | } 20 | list.head = data 21 | } 22 | 23 | func (list *LinkedList) InsertLast(i int) { 24 | data := &Node{data: i} 25 | if list.head == nil { 26 | list.head = data 27 | list.tail = data 28 | return 29 | } 30 | if list.tail != nil { 31 | list.tail.next = data 32 | data.prev = list.tail 33 | } 34 | list.tail = data 35 | } 36 | 37 | func (list *LinkedList) RemoveByValue(i int) bool { 38 | if list.head == nil { 39 | return false 40 | } 41 | if list.head.data == i { 42 | list.head = list.head.next 43 | list.head.prev = nil 44 | return true 45 | } 46 | if list.tail.data == i { 47 | list.tail = list.tail.prev 48 | list.tail.next = nil 49 | return true 50 | } 51 | current := list.head 52 | for current.next != nil { 53 | if current.next.data == i { 54 | if current.next.next != nil { 55 | current.next.next.prev = current 56 | } 57 | current.next = current.next.next 58 | return true 59 | } 60 | current = current.next 61 | } 62 | return false 63 | } 64 | 65 | func (list *LinkedList) RemoveByIndex(i int) bool { 66 | if list.head == nil { 67 | return false 68 | } 69 | if i < 0 { 70 | return false 71 | } 72 | if i == 0 { 73 | list.head.prev = nil 74 | list.head = list.head.next 75 | return true 76 | } 77 | current := list.head 78 | for u := 1; u < i; u++ { 79 | if current.next.next == nil { 80 | return false 81 | } 82 | current = current.next 83 | } 84 | if current.next.next != nil { 85 | current.next.next.prev = current 86 | } 87 | current.next = current.next.next 88 | return true 89 | } 90 | 91 | func (list *LinkedList) SearchValue(i int) bool { 92 | if list.head == nil { 93 | return false 94 | } 95 | current := list.head 96 | for current != nil { 97 | if current.data == i { 98 | return true 99 | } 100 | current = current.next 101 | } 102 | return false 103 | } 104 | 105 | func (list *LinkedList) GetFirst() (int, bool) { 106 | if list.head == nil { 107 | return 0, false 108 | } 109 | return list.head.data, true 110 | } 111 | 112 | func (list *LinkedList) GetLast() (int, bool) { 113 | if list.head == nil { 114 | return 0, false 115 | } 116 | current := list.head 117 | for current.next != nil { 118 | current = current.next 119 | } 120 | return current.data, true 121 | } 122 | 123 | func (list *LinkedList) GetSize() int { 124 | count := 0 125 | current := list.head 126 | for current != nil { 127 | count += 1 128 | current = current.next 129 | } 130 | 131 | return count 132 | } 133 | 134 | func (list *LinkedList) GetItemsFromStart() []int { 135 | var items []int 136 | current := list.head 137 | for current != nil { 138 | items = append(items, current.data) 139 | current = current.next 140 | } 141 | return items 142 | } 143 | 144 | func (list *LinkedList) GetItemsFromEnd() []int { 145 | var items []int 146 | current := list.tail 147 | for current != nil { 148 | items = append(items, current.data) 149 | current = current.prev 150 | } 151 | return items 152 | } 153 | -------------------------------------------------------------------------------- /ExponentialSearch/ExponentialSearch.go: -------------------------------------------------------------------------------- 1 | package ExponentialSearch 2 | 3 | func ExponentialSearch(array []int, number int) int { 4 | boundValue := 1 5 | for boundValue < len(array) && array[boundValue] < number { 6 | boundValue *= 2 7 | } 8 | if boundValue > len(array) { 9 | boundValue = len(array) - 1 10 | } 11 | return BinarySearch(array, boundValue+1, number) 12 | } 13 | 14 | func BinarySearch(array []int, bound, number int) int { 15 | minIndex := 0 16 | maxIndex := bound - 1 17 | for minIndex <= maxIndex { 18 | midIndex := int((maxIndex + minIndex) / 2) 19 | midItem := array[midIndex] 20 | if number == midItem { 21 | return midIndex 22 | } 23 | if midItem < number { 24 | minIndex = midIndex + 1 25 | } else if midItem > number { 26 | maxIndex = midIndex - 1 27 | } 28 | } 29 | return -1 30 | } 31 | -------------------------------------------------------------------------------- /ExponentialSearch/ExponentialSearch_test.go: -------------------------------------------------------------------------------- 1 | package ExponentialSearch 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func SortArray(array []int) { 10 | for itemIndex, itemValue := range array { 11 | for itemIndex != 0 && array[itemIndex-1] > itemValue { 12 | array[itemIndex] = array[itemIndex-1] 13 | itemIndex -= 1 14 | } 15 | array[itemIndex] = itemValue 16 | } 17 | } 18 | 19 | func TestExponentialSearch(t *testing.T) { 20 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 21 | array := make([]int, random.Intn(100-10)+10) 22 | for i := range array { 23 | array[i] = random.Intn(100) 24 | } 25 | SortArray(array) 26 | for _, value := range array { 27 | result := ExponentialSearch(array, value) 28 | if result == -1 { 29 | t.Fail() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /GnomeSort/GnomeSort.go: -------------------------------------------------------------------------------- 1 | package GnomeSort 2 | 3 | func GnomeSort(array []int) { 4 | itemIndex := 0 5 | for itemIndex < len(array)-1 { 6 | if array[itemIndex] > array[itemIndex+1] { 7 | array[itemIndex], array[itemIndex+1] = array[itemIndex+1], array[itemIndex] 8 | if itemIndex != 0 { 9 | itemIndex -= 1 10 | } 11 | } else { 12 | itemIndex += 1 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /GnomeSort/GnomeSort_test.go: -------------------------------------------------------------------------------- 1 | package GnomeSort 2 | 3 | import ( 4 | "math/rand" 5 | "sort" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestGnomeSort(t *testing.T) { 11 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 12 | array1 := make([]int, random.Intn(100-10)+10) 13 | for i := range array1 { 14 | array1[i] = random.Intn(100) 15 | } 16 | array2 := make(sort.IntSlice, len(array1)) 17 | copy(array2, array1) 18 | GnomeSort(array1) 19 | array2.Sort() 20 | for i := range array1 { 21 | if array1[i] != array2[i] { 22 | t.Fail() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /HashTable/HashTable.go: -------------------------------------------------------------------------------- 1 | package HashTable 2 | 3 | import "hash/fnv" 4 | 5 | type TableItem struct { 6 | key string 7 | data int 8 | next *TableItem 9 | } 10 | 11 | type HashTable struct { 12 | data [256]*TableItem 13 | } 14 | 15 | func (table *HashTable) Add(key string, i int) { 16 | position := generateHash(key) 17 | if table.data[position] == nil { 18 | table.data[position] = &TableItem{key: key, data: i} 19 | return 20 | } 21 | current := table.data[position] 22 | for current.next != nil { 23 | current = current.next 24 | } 25 | current.next = &TableItem{key: key, data: i} 26 | } 27 | 28 | func (table *HashTable) Get(key string) (int, bool) { 29 | position := generateHash(key) 30 | current := table.data[position] 31 | for current != nil { 32 | if current.key == key { 33 | return current.data, true 34 | } 35 | current = current.next 36 | } 37 | return 0, false 38 | } 39 | 40 | func (table *HashTable) Set(key string, value int) bool { 41 | position := generateHash(key) 42 | current := table.data[position] 43 | for current != nil { 44 | if current.key == key { 45 | current.data = value 46 | return true 47 | } 48 | current = current.next 49 | } 50 | return false 51 | } 52 | 53 | func (table *HashTable) Remove(key string) bool { 54 | position := generateHash(key) 55 | if table.data[position] == nil { 56 | return false 57 | } 58 | if table.data[position].key == key { 59 | table.data[position] = table.data[position].next 60 | return true 61 | } 62 | current := table.data[position] 63 | for current.next != nil { 64 | if current.next.key == key { 65 | current.next = current.next.next 66 | return true 67 | } 68 | current = current.next 69 | } 70 | return false 71 | } 72 | 73 | func generateHash(s string) uint8 { 74 | hash := fnv.New32a() 75 | hash.Write([]byte(s)) 76 | return uint8(hash.Sum32() % 256) 77 | } 78 | -------------------------------------------------------------------------------- /InsertionSort/InsertionSort.go: -------------------------------------------------------------------------------- 1 | package InsertionSort 2 | 3 | func InsertionSort(array []int) { 4 | for itemIndex, itemValue := range array { 5 | for itemIndex != 0 && array[itemIndex-1] > itemValue { 6 | array[itemIndex] = array[itemIndex-1] 7 | itemIndex -= 1 8 | } 9 | array[itemIndex] = itemValue 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /InsertionSort/InsertionSort_test.go: -------------------------------------------------------------------------------- 1 | package InsertionSort 2 | 3 | import ( 4 | "math/rand" 5 | "sort" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestInsertionSort(t *testing.T) { 11 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 12 | array1 := make([]int, random.Intn(100-10)+10) 13 | for i := range array1 { 14 | array1[i] = random.Intn(100) 15 | } 16 | array2 := make(sort.IntSlice, len(array1)) 17 | copy(array2, array1) 18 | InsertionSort(array1) 19 | array2.Sort() 20 | for i := range array1 { 21 | if array1[i] != array2[i] { 22 | t.Fail() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /InterpolationSearch/InterpolationSearch.go: -------------------------------------------------------------------------------- 1 | package InterpolationSearch 2 | 3 | func InterpolationSearch(array []int, number int) int { 4 | minIndex := 0 5 | maxIndex := len(array) - 1 6 | for minIndex <= maxIndex && number >= array[minIndex] && number <= array[maxIndex] { 7 | midIndex := minIndex + (number-array[minIndex])*(maxIndex-minIndex)/(array[maxIndex]-array[minIndex]) 8 | midItem := array[midIndex] 9 | if midItem == number { 10 | return midIndex 11 | } else if midItem < number { 12 | minIndex = midIndex + 1 13 | } else if midItem > number { 14 | maxIndex = midIndex - 1 15 | } 16 | } 17 | return -1 18 | } 19 | -------------------------------------------------------------------------------- /InterpolationSearch/InterpolationSearch_test.go: -------------------------------------------------------------------------------- 1 | package InterpolationSearch 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func SortArray(array []int) { 10 | for itemIndex, itemValue := range array { 11 | for itemIndex != 0 && array[itemIndex-1] > itemValue { 12 | array[itemIndex] = array[itemIndex-1] 13 | itemIndex -= 1 14 | } 15 | array[itemIndex] = itemValue 16 | } 17 | } 18 | 19 | func TestInterpolationSearch(t *testing.T) { 20 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 21 | array := make([]int, random.Intn(100-10)+10) 22 | for i := range array { 23 | array[i] = random.Intn(100) 24 | } 25 | SortArray(array) 26 | for _, value := range array { 27 | result := InterpolationSearch(array, value) 28 | if result == -1 { 29 | t.Fail() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /JumpSearch/JumpSearch.go: -------------------------------------------------------------------------------- 1 | package JumpSearch 2 | 3 | import "math" 4 | 5 | func JumpSearch(array []int, number int) int { 6 | jumpValue := int(math.Floor(math.Sqrt(float64(len(array))))) 7 | minIndex := 0 8 | maxIndex := jumpValue 9 | for array[maxIndex] <= number { 10 | minIndex += jumpValue 11 | maxIndex = minIndex + jumpValue 12 | if maxIndex >= len(array) { 13 | maxIndex = len(array) 14 | minIndex = maxIndex - jumpValue 15 | break 16 | } 17 | } 18 | for i := minIndex; i < maxIndex; i++ { 19 | if array[i] == number { 20 | return i 21 | } 22 | } 23 | return -1 24 | } 25 | -------------------------------------------------------------------------------- /JumpSearch/JumpSearch_test.go: -------------------------------------------------------------------------------- 1 | package JumpSearch 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func SortArray(array []int) { 10 | for itemIndex, itemValue := range array { 11 | for itemIndex != 0 && array[itemIndex-1] > itemValue { 12 | array[itemIndex] = array[itemIndex-1] 13 | itemIndex -= 1 14 | } 15 | array[itemIndex] = itemValue 16 | } 17 | } 18 | 19 | func TestJumpSearch(t *testing.T) { 20 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 21 | array := make([]int, random.Intn(100-10)+10) 22 | for i := range array { 23 | array[i] = random.Intn(100) 24 | } 25 | SortArray(array) 26 | for _, value := range array { 27 | result := JumpSearch(array, value) 28 | if result == -1 { 29 | t.Fail() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mykyta Paliienko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LinearSearch/LinearSearch.go: -------------------------------------------------------------------------------- 1 | package LinearSearch 2 | 3 | func LinearSearch(array []int, number int) int { 4 | for index, value := range array { 5 | if value == number { 6 | return index 7 | } 8 | } 9 | return -1 10 | } 11 | -------------------------------------------------------------------------------- /LinearSearch/LinearSearch_test.go: -------------------------------------------------------------------------------- 1 | package LinearSearch 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func SortArray(array []int) { 10 | for itemIndex, itemValue := range array { 11 | for itemIndex != 0 && array[itemIndex-1] > itemValue { 12 | array[itemIndex] = array[itemIndex-1] 13 | itemIndex -= 1 14 | } 15 | array[itemIndex] = itemValue 16 | } 17 | } 18 | 19 | func TestLinearSearch(t *testing.T) { 20 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 21 | array := make([]int, random.Intn(100-10)+10) 22 | for i := range array { 23 | array[i] = random.Intn(100) 24 | } 25 | SortArray(array) 26 | for _, value := range array { 27 | result := LinearSearch(array, value) 28 | if result == -1 { 29 | t.Fail() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LinkedList/LinkedList.go: -------------------------------------------------------------------------------- 1 | package LinkedList 2 | 3 | type Node struct { 4 | data int 5 | next *Node 6 | } 7 | 8 | type LinkedList struct { 9 | head *Node 10 | } 11 | 12 | func (list *LinkedList) InsertFirst(i int) { 13 | data := &Node{data: i} 14 | if list.head != nil { 15 | data.next = list.head 16 | } 17 | list.head = data 18 | } 19 | 20 | func (list *LinkedList) InsertLast(i int) { 21 | data := &Node{data: i} 22 | if list.head == nil { 23 | list.head = data 24 | return 25 | } 26 | current := list.head 27 | for current.next != nil { 28 | current = current.next 29 | } 30 | current.next = data 31 | } 32 | 33 | func (list *LinkedList) RemoveByValue(i int) bool { 34 | if list.head == nil { 35 | return false 36 | } 37 | if list.head.data == i { 38 | list.head = list.head.next 39 | return true 40 | } 41 | current := list.head 42 | for current.next != nil { 43 | if current.next.data == i { 44 | current.next = current.next.next 45 | return true 46 | } 47 | current = current.next 48 | } 49 | return false 50 | } 51 | 52 | func (list *LinkedList) RemoveByIndex(i int) bool { 53 | if list.head == nil { 54 | return false 55 | } 56 | if i < 0 { 57 | return false 58 | } 59 | if i == 0 { 60 | list.head = list.head.next 61 | return true 62 | } 63 | current := list.head 64 | for u := 1; u < i; u++ { 65 | if current.next.next == nil { 66 | return false 67 | } 68 | current = current.next 69 | } 70 | current.next = current.next.next 71 | return true 72 | } 73 | 74 | func (list *LinkedList) SearchValue(i int) bool { 75 | if list.head == nil { 76 | return false 77 | } 78 | current := list.head 79 | for current != nil { 80 | if current.data == i { 81 | return true 82 | } 83 | current = current.next 84 | } 85 | return false 86 | } 87 | 88 | func (list *LinkedList) GetFirst() (int, bool) { 89 | if list.head == nil { 90 | return 0, false 91 | } 92 | return list.head.data, true 93 | } 94 | 95 | func (list *LinkedList) GetLast() (int, bool) { 96 | if list.head == nil { 97 | return 0, false 98 | } 99 | current := list.head 100 | for current.next != nil { 101 | current = current.next 102 | } 103 | return current.data, true 104 | } 105 | 106 | func (list *LinkedList) GetSize() int { 107 | count := 0 108 | current := list.head 109 | for current != nil { 110 | count += 1 111 | current = current.next 112 | } 113 | return count 114 | } 115 | 116 | func (list *LinkedList) GetItems() []int { 117 | var items []int 118 | current := list.head 119 | for current != nil { 120 | items = append(items, current.data) 121 | current = current.next 122 | } 123 | return items 124 | } 125 | -------------------------------------------------------------------------------- /MergeSort/MergeSort.go: -------------------------------------------------------------------------------- 1 | package MergeSort 2 | 3 | func mergeParts(array []int, leftIndex, divideIndex, rightIndex int) { 4 | var tempArray1, tempArray2 []int 5 | for i := leftIndex; i <= divideIndex; i++ { 6 | tempArray1 = append(tempArray1, array[i]) 7 | } 8 | for i := divideIndex + 1; i <= rightIndex; i++ { 9 | tempArray2 = append(tempArray2, array[i]) 10 | } 11 | arrayIndex := leftIndex 12 | tempArray1Index := 0 13 | tempArray2Index := 0 14 | for tempArray1Index != len(tempArray1) && tempArray2Index != len(tempArray2) { 15 | if tempArray1[tempArray1Index] <= tempArray2[tempArray2Index] { 16 | array[arrayIndex] = tempArray1[tempArray1Index] 17 | tempArray1Index += 1 18 | } else { 19 | array[arrayIndex] = tempArray2[tempArray2Index] 20 | tempArray2Index += 1 21 | } 22 | arrayIndex += 1 23 | } 24 | for tempArray1Index < len(tempArray1) { 25 | array[arrayIndex] = tempArray1[tempArray1Index] 26 | tempArray1Index += 1 27 | arrayIndex += 1 28 | 29 | } 30 | for tempArray2Index < len(tempArray2) { 31 | array[arrayIndex] = tempArray2[tempArray2Index] 32 | tempArray2Index += 1 33 | arrayIndex += 1 34 | } 35 | } 36 | 37 | func MergeSort(array []int, leftIndex, rightIndex int) { 38 | if leftIndex >= rightIndex { 39 | return 40 | } 41 | divideIndex := int((leftIndex + rightIndex) / 2) 42 | MergeSort(array, leftIndex, divideIndex) 43 | MergeSort(array, divideIndex+1, rightIndex) 44 | mergeParts(array, leftIndex, divideIndex, rightIndex) 45 | } 46 | -------------------------------------------------------------------------------- /MergeSort/MergeSort_test.go: -------------------------------------------------------------------------------- 1 | package MergeSort 2 | 3 | import ( 4 | "math/rand" 5 | "sort" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestSelectionSort(t *testing.T) { 11 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 12 | array1 := make([]int, random.Intn(100-10)+10) 13 | for i := range array1 { 14 | array1[i] = random.Intn(100) 15 | } 16 | array2 := make(sort.IntSlice, len(array1)) 17 | copy(array2, array1) 18 | MergeSort(array1, 0, len(array1)-1) 19 | array2.Sort() 20 | for i := range array1 { 21 | if array1[i] != array2[i] { 22 | t.Fail() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NaiveStringSearch/NaiveStringSearch.go: -------------------------------------------------------------------------------- 1 | package NaiveStringSearch 2 | 3 | func NaiveStringSearch(text, pattern string) int { 4 | textLength := len(text) 5 | patternLength := len(pattern) 6 | if patternLength > textLength { 7 | return -1 8 | } 9 | for i := 0; i < textLength-patternLength+1; i++ { 10 | matchesCount := 0 11 | for j := 0; j < patternLength; j++ { 12 | if text[i+j] != pattern[j] { 13 | break 14 | } 15 | matchesCount++ 16 | } 17 | if matchesCount == patternLength { 18 | return i 19 | } 20 | } 21 | return -1 22 | } 23 | -------------------------------------------------------------------------------- /NaiveStringSearch/NaiveStringSearch_test.go: -------------------------------------------------------------------------------- 1 | package NaiveStringSearch 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestNaiveStringSearch(t *testing.T) { 10 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 11 | letters := []rune("abcdefghijklmnopqrstuvwxyz") 12 | text := make([]rune, random.Intn(15-10)+10) 13 | for i := range text { 14 | text[i] = letters[rand.Intn(len(letters))] 15 | } 16 | end := random.Intn(len(text)-5) + 5 17 | start := random.Intn(end) 18 | result := NaiveStringSearch(string(text), string(text[start:end])) 19 | if result == -1 { 20 | t.Fail() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Queue(LinkedList)/Queue.go: -------------------------------------------------------------------------------- 1 | package QueueLinkedList 2 | 3 | type Node struct { 4 | data int 5 | next *Node 6 | } 7 | 8 | type Queue struct { 9 | rear *Node 10 | } 11 | 12 | func (list *Queue) Enqueue(i int) { 13 | data := &Node{data: i} 14 | if list.rear != nil { 15 | data.next = list.rear 16 | } 17 | list.rear = data 18 | } 19 | 20 | func (list *Queue) Dequeue() (int, bool) { 21 | if list.rear == nil { 22 | return 0, false 23 | } 24 | if list.rear.next == nil { 25 | i := list.rear.data 26 | list.rear = nil 27 | return i, true 28 | } 29 | current := list.rear 30 | for { 31 | if current.next.next == nil { 32 | i := current.next.data 33 | current.next = nil 34 | return i, true 35 | } 36 | current = current.next 37 | } 38 | } 39 | 40 | func (list *Queue) Peek() (int, bool) { 41 | if list.rear == nil { 42 | return 0, false 43 | } 44 | return list.rear.data, true 45 | } 46 | 47 | func (list *Queue) Get() []int { 48 | var items []int 49 | current := list.rear 50 | for current != nil { 51 | items = append(items, current.data) 52 | current = current.next 53 | } 54 | return items 55 | } 56 | 57 | func (list *Queue) IsEmpty() bool { 58 | return list.rear == nil 59 | } 60 | 61 | func (list *Queue) Empty() { 62 | list.rear = nil 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures and Algorithms 2 | 3 | [![Go Report Card](https://goreportcard.com/badge/github.com/floyernick/Data-Structures-and-Algorithms)](https://goreportcard.com/report/github.com/floyernick/Data-Structures-and-Algorithms) [![Build Status](https://travis-ci.org/floyernick/Data-Structures-and-Algorithms.svg?branch=master)](https://travis-ci.org/floyernick/Data-Structures-and-Algorithms) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/floyernick/Data-Structures-and-Algorithms/blob/master/LICENSE) 4 | 5 | Clean and simple implementation in Go 6 | 7 | ## Implementation 8 | 9 | There are several data structures and algorithms implemented in this project. The list will be replenished with time. 10 | 11 | ##### Data structures 12 | - Circular Buffer 13 | - Linked List 14 | - Doubly Linked List 15 | - Stack 16 | - Queue 17 | - Binary Tree 18 | - Hash Table 19 | - Trie 20 | 21 | ##### Searching algorithms 22 | - Linear Search 23 | - Binary Search 24 | - Jump Search 25 | - Interpolation Search 26 | - Exponential Search 27 | - Ternary Search 28 | 29 | ##### String searching algorithms 30 | 31 | - Naive String Search 32 | - Rabin-Karp Algorithm 33 | 34 | ##### Sorting algorithms 35 | - Selection Sort 36 | - Insertion Sort 37 | - Bubble Sort 38 | - Comb Sort 39 | - Cocktail Sort 40 | - Gnome Sort 41 | - Merge Sort 42 | 43 | ## Usage 44 | 45 | The library is not intended for direct use by importing. We strongly recommend copying the necessary implementations and adjusting to your case. 46 | 47 | You can download the source using `go get` command: 48 | 49 | ``` 50 | go get github.com/floyernick/Data-Structures-and-Algorithms 51 | ``` 52 | 53 | Don't forget about proverb: 54 | > A little copying is better than a little dependency. 55 | 56 | ## Contribute 57 | 58 | We would be happy to receive your propositions of improvement! Read [Contributing Guide](https://github.com/floyernick/Data-Structures-and-Algorithms/blob/master/CONTRIBUTING.md) for more details. 59 | 60 | ## License 61 | 62 | This project is licensed under the **MIT License**. 63 | 64 | ## Authors 65 | 66 | **Mykyta Paliienko** - [GitHub profile](https://github.com/floyernick) -------------------------------------------------------------------------------- /RabinKarp/RabinKarp.go: -------------------------------------------------------------------------------- 1 | package RabinKarp 2 | 3 | import "hash/adler32" 4 | 5 | func calculateHash(text string) uint32 { 6 | return adler32.Checksum([]byte(text)) 7 | } 8 | 9 | func RabinKarp(text, pattern string) int { 10 | textLength := len(text) 11 | patternLength := len(pattern) 12 | if patternLength > textLength { 13 | return -1 14 | } 15 | for i := 0; i < textLength-patternLength+1; i++ { 16 | if calculateHash(pattern) != calculateHash(text[i:i+patternLength]) { 17 | continue 18 | } 19 | matchesCount := 0 20 | for j := 0; j < patternLength; j++ { 21 | if text[i+j] != pattern[j] { 22 | break 23 | } 24 | matchesCount++ 25 | } 26 | if matchesCount == patternLength { 27 | return i 28 | } 29 | } 30 | return -1 31 | } 32 | -------------------------------------------------------------------------------- /RabinKarp/RabinKarp_test.go: -------------------------------------------------------------------------------- 1 | package RabinKarp 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestRabinKarp(t *testing.T) { 10 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 11 | letters := []rune("abcdefghijklmnopqrstuvwxyz") 12 | text := make([]rune, random.Intn(15-10)+10) 13 | for i := range text { 14 | text[i] = letters[rand.Intn(len(letters))] 15 | } 16 | end := random.Intn(len(text)-5) + 5 17 | start := random.Intn(end) 18 | result := RabinKarp(string(text), string(text[start:end])) 19 | if result == -1 { 20 | t.Fail() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ReverseArray/ReverseArray.go: -------------------------------------------------------------------------------- 1 | package ReverseArray 2 | 3 | func ReverseArray(a []int) { 4 | i := 0 5 | u := len(a) - 1 6 | for i < u { 7 | a[i], a[u] = a[u], a[i] 8 | i, u = i+1, u-1 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SelectionSort/SelectionSort.go: -------------------------------------------------------------------------------- 1 | package SelectionSort 2 | 3 | func SelectionSort(array []int) { 4 | for arrayIndex := range array { 5 | minValue := array[arrayIndex] 6 | minIndex := arrayIndex 7 | for subArrayIndex := arrayIndex + 1; subArrayIndex < len(array); subArrayIndex++ { 8 | if array[subArrayIndex] < minValue { 9 | minValue = array[subArrayIndex] 10 | minIndex = subArrayIndex 11 | } 12 | } 13 | array[minIndex], array[arrayIndex] = array[arrayIndex], array[minIndex] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SelectionSort/SelectionSort_test.go: -------------------------------------------------------------------------------- 1 | package SelectionSort 2 | 3 | import ( 4 | "math/rand" 5 | "sort" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestSelectionSort(t *testing.T) { 11 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 12 | array1 := make([]int, random.Intn(100-10)+10) 13 | for i := range array1 { 14 | array1[i] = random.Intn(100) 15 | } 16 | array2 := make(sort.IntSlice, len(array1)) 17 | copy(array2, array1) 18 | SelectionSort(array1) 19 | array2.Sort() 20 | for i := range array1 { 21 | if array1[i] != array2[i] { 22 | t.Fail() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Stack(Array)/Stack.go: -------------------------------------------------------------------------------- 1 | package StackArray 2 | 3 | const arraySize = 10 4 | 5 | type Stack struct { 6 | top int 7 | data [arraySize]int 8 | } 9 | 10 | func (s *Stack) Push(i int) bool { 11 | if s.top == len(s.data) { 12 | return false 13 | } 14 | s.data[s.top] = i 15 | s.top += 1 16 | return true 17 | } 18 | 19 | func (s *Stack) Pop() (int, bool) { 20 | if s.top == 0 { 21 | return 0, false 22 | } 23 | i := s.data[s.top-1] 24 | s.top -= 1 25 | return i, true 26 | } 27 | 28 | func (s *Stack) Peek() int { 29 | return s.data[s.top-1] 30 | } 31 | 32 | func (s *Stack) Get() []int { 33 | return s.data[:s.top] 34 | } 35 | 36 | func (s *Stack) IsEmpty() bool { 37 | return s.top == 0 38 | } 39 | 40 | func (s *Stack) Empty() { 41 | s.top = 0 42 | } 43 | -------------------------------------------------------------------------------- /Stack(LinkedList)/Stack.go: -------------------------------------------------------------------------------- 1 | package StackLinkedList 2 | 3 | type Node struct { 4 | data int 5 | next *Node 6 | } 7 | 8 | type Stack struct { 9 | top *Node 10 | } 11 | 12 | func (list *Stack) Push(i int) { 13 | data := &Node{data: i} 14 | if list.top != nil { 15 | data.next = list.top 16 | } 17 | list.top = data 18 | } 19 | 20 | func (list *Stack) Pop() (int, bool) { 21 | if list.top == nil { 22 | return 0, false 23 | } 24 | i := list.top.data 25 | list.top = list.top.next 26 | return i, true 27 | } 28 | 29 | func (list *Stack) Peek() (int, bool) { 30 | if list.top == nil { 31 | return 0, false 32 | } 33 | return list.top.data, true 34 | } 35 | 36 | func (list *Stack) Get() []int { 37 | 38 | var items []int 39 | 40 | current := list.top 41 | for current != nil { 42 | items = append(items, current.data) 43 | current = current.next 44 | } 45 | return items 46 | } 47 | 48 | func (list *Stack) IsEmpty() bool { 49 | return list.top == nil 50 | } 51 | 52 | func (list *Stack) Empty() { 53 | list.top = nil 54 | } 55 | -------------------------------------------------------------------------------- /TernarySearch/TernarySearch.go: -------------------------------------------------------------------------------- 1 | package TernarySearch 2 | 3 | func TernarySearch(array []int, number int) int { 4 | minIndex := 0 5 | maxIndex := len(array) - 1 6 | for minIndex <= maxIndex { 7 | midIndex1 := minIndex + int((maxIndex-minIndex)/3) 8 | midIndex2 := maxIndex - int((maxIndex-minIndex)/3) 9 | midItem1 := array[midIndex1] 10 | midItem2 := array[midIndex2] 11 | if midItem1 == number { 12 | return midIndex1 13 | } else if midItem2 == number { 14 | return midIndex2 15 | } 16 | if midItem1 < number { 17 | minIndex = midIndex1 + 1 18 | } else if midItem2 > number { 19 | maxIndex = midIndex2 - 1 20 | } else { 21 | minIndex = midIndex1 + 1 22 | maxIndex = midIndex2 - 1 23 | } 24 | } 25 | return -1 26 | } 27 | -------------------------------------------------------------------------------- /TernarySearch/TernarySearch_test.go: -------------------------------------------------------------------------------- 1 | package TernarySearch 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func SortArray(array []int) { 10 | for itemIndex, itemValue := range array { 11 | for itemIndex != 0 && array[itemIndex-1] > itemValue { 12 | array[itemIndex] = array[itemIndex-1] 13 | itemIndex -= 1 14 | } 15 | array[itemIndex] = itemValue 16 | } 17 | } 18 | 19 | func TestTernarySearch(t *testing.T) { 20 | random := rand.New(rand.NewSource(time.Now().UnixNano())) 21 | array := make([]int, random.Intn(100-10)+10) 22 | for i := range array { 23 | array[i] = random.Intn(100) 24 | } 25 | SortArray(array) 26 | for _, value := range array { 27 | result := TernarySearch(array, value) 28 | if result == -1 { 29 | t.Fail() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Trie/Trie.go: -------------------------------------------------------------------------------- 1 | package Trie 2 | 3 | type Node struct { 4 | last bool 5 | parent *Node 6 | children map[int32]*Node 7 | } 8 | 9 | type Trie struct { 10 | root *Node 11 | } 12 | 13 | func (trie *Trie) Init() { 14 | trie.root = &Node{children: map[int32]*Node{}} 15 | } 16 | 17 | func (trie Trie) Add(item string) { 18 | currentNode := trie.root 19 | for _, r := range item { 20 | if _, ok := currentNode.children[r]; ok { 21 | currentNode = currentNode.children[r] 22 | } else { 23 | node := &Node{children: map[int32]*Node{}, parent: currentNode} 24 | currentNode.children[r] = node 25 | currentNode = node 26 | } 27 | } 28 | currentNode.last = true 29 | } 30 | 31 | func (trie Trie) Search(item string) bool { 32 | currentNode := trie.root 33 | for _, r := range item { 34 | if _, ok := currentNode.children[r]; ok { 35 | currentNode = currentNode.children[r] 36 | } else { 37 | return false 38 | } 39 | } 40 | if currentNode.last == false { 41 | return false 42 | } 43 | return true 44 | } 45 | 46 | func (trie Trie) Remove(item string) bool { 47 | currentNode := trie.root 48 | for _, r := range item { 49 | if _, ok := currentNode.children[r]; ok { 50 | currentNode = currentNode.children[r] 51 | } else { 52 | return false 53 | } 54 | } 55 | if currentNode.last == false { 56 | return false 57 | } 58 | currentNode.last = false 59 | symbolIndex := len(item) - 1 60 | for len(currentNode.children) == 0 { 61 | delete(currentNode.children, int32(item[symbolIndex])) 62 | currentNode = currentNode.parent 63 | symbolIndex-- 64 | } 65 | return true 66 | } 67 | -------------------------------------------------------------------------------- /dsa.go: -------------------------------------------------------------------------------- 1 | package dsa 2 | --------------------------------------------------------------------------------