├── .DS_Store ├── .github ├── CODEOWNERS └── workflows │ ├── codeql-analysis.yml │ └── go.yml ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── adjaceny-list-graph ├── adjacency-list-graph.go └── adjacency-list-graph_test.go ├── allpairs ├── allpairs.go └── allpairs_test.go ├── bst ├── binarySearchTree.go └── binarySearchTree_test.go ├── btree ├── btree.go └── btree_test.go ├── bubblesort ├── bubblesort.go └── bubblesort_test.go ├── convexHull ├── convexHull.go └── convexHull_test.go ├── doc ├── gopher.jpg └── logo.png ├── graph ├── graph.go └── graph_test.go ├── heapsort ├── heapsort.go └── heapsort_test.go ├── insertsort ├── insertsort.go └── insertsort_test.go ├── knuthMorrisPratt ├── knuthMorrisPratt.go └── knuthMorrisPratt_test.go ├── kruskal ├── dsu.go ├── dsu_test.go ├── kruskal.go └── kruskal_test.go ├── linked-list ├── linked-list.go └── linked-list_test.go ├── ludecomposition ├── ludecomposition.go └── ludecomposition_test.go ├── mergesort ├── mergesort.go └── mergesort_test.go ├── qsort ├── qsort.go └── qsort_test.go ├── queuestack ├── queue.go ├── queue_test.go ├── stack.go └── stack_test.go ├── rabinkarp ├── rabinkarp.go └── rabinkarp_test.go ├── rbtree ├── rbtree.go └── rbtree_test.go └── stack ├── stack.go └── stack_test.go /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch3ck/algo/5aae7fab9e3d6ebca20ee30441c232f43815b89b/.DS_Store -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # CODE OWNERS 2 | 3 | * @ch3ck 4 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # ******** NOTE ******** 2 | # We have attempted to detect the languages in your repository. Please check 3 | # the `language` matrix defined below to confirm you have the correct set of 4 | # supported CodeQL languages. 5 | # 6 | name: "CodeQL" 7 | 8 | on: 9 | push: 10 | branches: [ master ] 11 | pull_request: 12 | # The branches below must be a subset of the branches above 13 | branches: [ master ] 14 | schedule: 15 | - cron: '35 22 * * 3' 16 | 17 | jobs: 18 | analyze: 19 | name: Analyze 20 | runs-on: ubuntu-latest 21 | permissions: 22 | actions: read 23 | contents: read 24 | security-events: write 25 | 26 | strategy: 27 | fail-fast: false 28 | matrix: 29 | language: [ 'go' ] 30 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 31 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 32 | 33 | steps: 34 | - name: Checkout repository 35 | uses: actions/checkout@v2 36 | 37 | # Initializes the CodeQL tools for scanning. 38 | - name: Initialize CodeQL 39 | uses: github/codeql-action/init@v1 40 | with: 41 | languages: ${{ matrix.language }} 42 | # If you wish to specify custom queries, you can do so here or in a config file. 43 | # By default, queries listed here will override any specified in a config file. 44 | # Prefix the list here with "+" to use these queries and those in the config file. 45 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 46 | 47 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 48 | # If this step fails, then you should remove it and run the build manually (see below) 49 | - name: Autobuild 50 | uses: github/codeql-action/autobuild@v1 51 | 52 | # ℹ️ Command-line programs to run using the OS shell. 53 | # 📚 https://git.io/JvXDl 54 | 55 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 56 | # and modify them (or add more) to build your code if your project 57 | # uses a compiled language 58 | 59 | #- run: | 60 | # make bootstrap 61 | # make release 62 | 63 | - name: Perform CodeQL Analysis 64 | uses: github/codeql-action/analyze@v1 65 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v2 18 | with: 19 | go-version: 1.17 20 | 21 | - name: Build 22 | run: go build -v ./... 23 | 24 | - name: Test 25 | run: go test -v ./... 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | .idea -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | before_install: 4 | - go get -u github.com/golang/lint/golint 5 | - golint ./... 6 | # - go vet ./... 7 | - diff -u <(echo-n) <(gofmt -s -d .) 8 | 9 | install: 10 | - go get -u -v $((go list -f '{{join .TestImports "\n"}}' ./... && go list -f '{{join .Imports "\n"}}' ./...) | sort | uniq | grep -v AlGo) 11 | 12 | script: 13 | - go test ./... 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Algo 2 | 3 | Want to hack on Algo? Awesome! We have a contributor's guide that explains 4 | how to add new features to this repository. 5 | 6 | ![Contributors guide](doc/gopher.jpg) 7 | 8 | This page contains information about reporting issues as well as some tips and 9 | guidelines useful to experienced open source contributors. Finally, make sure 10 | you read through before you start participating. 11 | 12 | 13 | ## Topics 14 | 15 | * [Data Structures](#) 16 | * [Algorithms](#) 17 | 18 | We have different Data structures and algorithms in mind which we created in the 19 | issues. 20 | 21 | Create a new 'package' for each new Data structure or Algorithm with it's unit test 22 | integrated in the /test directory. This test should easily be called and tested 23 | from the main package 24 | 25 | 26 | ### Conventions 27 | 28 | Fork the repository and make changes on your fork in a feature branch: 29 | 30 | - If it's a bug fix branch, name it XXXX-something where XXXX is the number of 31 | the issue. 32 | - If it's a feature branch, create an enhancement issue to announce 33 | your intentions, and name it XXXX-something where XXXX is the number of the 34 | issue. 35 | 36 | Submit unit tests for your changes. Go has a great test framework built in; use 37 | it! Take a look at existing tests for inspiration. Run the test on your branch before 38 | submitting a pull request. 39 | 40 | Update the documentation when creating or modifying features. Test your 41 | documentation changes for clarity, concision, and correctness, as well as a 42 | clean documentation build. 43 | 44 | Write clean code. Universally formatted code promotes ease of writing, reading, 45 | and maintenance. Always run `gofmt -s -w file.go` on each changed file before 46 | committing your changes. Most editors have plug-ins that do this automatically. 47 | 48 | Pull request descriptions should be as clear as possible and include a reference 49 | to all the issues that they address. 50 | 51 | Commit messages must start with a capitalized and short summary (max. 50 chars) 52 | written in the imperative, followed by an optional, more detailed explanatory 53 | text which is separated from the summary by an empty line. 54 | 55 | Code review comments may be added to your pull request. Discuss, then make the 56 | suggested modifications and push additional commits to your feature branch. Post 57 | a comment after pushing. New commits show up in the pull request automatically, 58 | but the reviewers are notified only when you comment. 59 | 60 | Pull requests must be cleanly rebased on top of master without multiple branches 61 | mixed into the PR. 62 | 63 | **Git tip**: If your PR no longer merges cleanly, use `rebase master` in your 64 | feature branch to update your pull request rather than `merge master`. 65 | 66 | 67 | Include an issue reference like `Closes #XXXX` or `Fixes #XXXX` in commits that 68 | close an issue. Including references automatically closes the issue on a merge. 69 | 70 | Please do not add yourself to the `AUTHORS` file, as it is regenerated regularly 71 | from the Git history. 72 | 73 | Please see the [Coding Style](#coding-style) for further guidelines. 74 | 75 | 76 | ## Sign your work 77 | 78 | The sign-off is a simple line at the end of the explanation for the patch. Your 79 | signature certifies that you wrote the patch or otherwise have the right to pass 80 | it on as an open-source patch. The rules are pretty simple: if you can certify 81 | the below (from [developercertificate.org](http://developercertificate.org/)). 82 | 83 | 84 | 85 | ## Communication guidelines 86 | 87 | We want to keep things awesome, growing and collaborative. We need 88 | your help to keep it that way. To help with this we've come up with some general 89 | guidelines for the community as a whole: 90 | 91 | * Be nice: Be courteous, respectful and polite to fellow community members: 92 | no regional, racial, gender, or other abuse will be tolerated. We like 93 | nice people way better than mean ones! 94 | 95 | * Encourage diversity and participation: Make everyone in our community feel 96 | welcome, regardless of their background and the extent of their 97 | contributions, and do everything possible to encourage participation in 98 | our community. 99 | 100 | * Keep it legal: Basically, don't get us in trouble. Share only content that 101 | you own, do not share private or sensitive information, and don't break 102 | the law. 103 | 104 | * Stay on topic: Make sure that you are posting to the correct channel and 105 | avoid off-topic discussions. Remember when you update an issue or respond 106 | to an email you are potentially sending to a large number of people. Please 107 | consider this before you update. Also remember that nobody likes spam. 108 | 109 | 110 | ## Coding Style 111 | 112 | Unless explicitly stated, we follow all coding guidelines from the Go 113 | community. While some of these standards may seem arbitrary, they somehow seem 114 | to result in a solid, consistent codebase. 115 | 116 | It is possible that the code base does not currently comply with these 117 | guidelines. We are not looking for a massive PR that fixes this, since that 118 | goes against the spirit of the guidelines. All new contributions should make a 119 | best effort to clean up and make the code base better than they left it. 120 | Obviously, apply your best judgement. Remember, the goal here is to make the 121 | code base easier for humans to navigate and understand. Always keep that in 122 | mind when nudging others to comply. 123 | 124 | The rules: 125 | 126 | 1. All code should be formatted with `gofmt -s`. 127 | 2. Comment the code. Tell us the why, the history and the context. 128 | 3. Document _all_ declarations and methods, even private ones. Declare 129 | expectations, caveats and anything else that may be important. If a type 130 | gets exported, having the comments already there will ensure it's ready. 131 | 132 | 133 | ## Questions 134 | 135 | If you have any further questions please feel free to reach out to [Nyah Check](nyah@ch3ck.me) 136 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Nyah Check 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AlGo [![Go Report Card](https://goreportcard.com/badge/github.com/Ch3ck/Algo)](https://goreportcard.com/report/github.com/Ch3ck/Algo) [![Build Status](https://travis-ci.org/Ch3ck/AlGo.svg?branch=master)](https://travis-ci.org/Ch3ck/AlGo) [![GitHub issues](https://img.shields.io/github/issues/Ch3ck/AlGo.svg)](https://github.com/Ch3ck/AlGo/issues) [![GitHub stars](https://img.shields.io/github/stars/Ch3ck/AlGo.svg)](https://github.com/Ch3ck/AlGo/stargazers) 2 | AlGo was created by, and is maintained by [Nyah Check](https://github.com/Ch3ck), and it's the Golang implementation of the Data Structures and Algorithms as referred in CLRS. 3 | 4 | Feel free to check out the [license](LICENSE), and make contributions by pull requests. 5 | 6 | ## Contributing 7 | 8 | Star and Fork this repo; then follow the instructions in [Contributing.md](CONTRIBUTING.md) 9 | 10 | ## Talking to other Devs and Contributors 11 | 12 | 13 | 14 | 15 | 16 | 17 | 26 | 27 | 32 | 33 |
Internet Relay Chat (IRC) 18 |

19 | IRC is a direct line to our most Algo contributors; we have 20 | both the #ublab group on 21 | irc.freenode.net. 22 | IRC is a rich chat protocol but it can overwhelm new users. You can search 23 | our chat archives. 24 |

25 |
Twitter 28 | You can follow Algo Maintainer 29 | to get updates; You can also tweet us questions or just 30 | share blogs or stories. 31 |
34 | 35 | ## License 36 | 37 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/Ch3ck/AlGo/master/LICENSE) 38 | 39 | ![Gopher](doc/logo.png "Gopher") 40 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /adjaceny-list-graph/adjacency-list-graph.go: -------------------------------------------------------------------------------- 1 | // SUMMARY 2 | // 3 | // This module implements a graph data structure using the adjacency 4 | // list implementation as defined by Goodrich, Tamassia & Goldwasser (2014) 5 | // in [1]. This implementation however makes some changes; most notably 6 | // is the use of a map data structure for the `primary structure` that holds 7 | // the vertices as compared to the array based data structure the authors suggested. 8 | // The Graph Abstract Data Type implemented is the same as the the one proposed 9 | // by the authors. 10 | // 11 | // As suggested by the authors, each vertex in the graph uses an will have 12 | // both outgoing and incoming list of edges, since the graph is directed. 13 | // 14 | // 15 | // REFERENCE 16 | // 17 | // [1] Goodrich, M. T., Tamassia, R., & Goldwasser, M. H. (2014). 18 | // Data structures and algorithms in Java. John Wiley & Sons. 19 | 20 | package adjaceny_list_graph 21 | 22 | import ( 23 | "github.com/Ch3ck/AlGo/queuestack" 24 | ) 25 | 26 | // A vertex (or node) in the graph. 27 | // Each vertex has the following attributes: 28 | // 29 | // id (int): a number to help access the node in O(1) time 30 | // item (interface): the item stored in the vertex 31 | // outgoingEdges (list.List): a list of the vertices, that along 32 | // with the current vertex form an outgoing edge. 33 | // incomingEdges (list.List): a list of the vertices, that along 34 | // with the current vertex form an outgoing edge. 35 | type vertex struct { 36 | id int 37 | item interface{} 38 | outgoingEdges []*edge 39 | incomingEdges []*edge 40 | } 41 | 42 | // An edge in the directed graph. 43 | // Each edge is represented as a 2-tuple struct that has the following attributes 44 | // 45 | // weight (interface): a value denoted the weight of an edge (when dealing with weighted graphs). 46 | // It is set to nil for unweighted graphs. 47 | // fromVertex (vertex): the vertex this edge starts from. The outgoing vertex. 48 | // toVertex (vertex): the vertex this edge is incident on. The incoming vertex. 49 | type edge struct { 50 | id int 51 | weight interface{} 52 | fromVertex *vertex 53 | toVertex *vertex 54 | } 55 | 56 | func NewEdge() *edge { 57 | return &edge{ 58 | 0, 59 | "sugar", 60 | new(vertex), 61 | new(vertex), 62 | } 63 | } 64 | 65 | // The Directed Adjacency List Graph. 66 | // 67 | // ATTRIBUTES 68 | // 69 | // primaryStructure (map[int]vertex): holds the vertices in the graph. A map is used 70 | // because it provides O(1) access to a node. 71 | // numVertices (int): The total number of vertices in the graph. 72 | // numEdges (int): The total number of edges in the graph. 73 | type DirectedAdjacencyListGraph struct { 74 | primaryStructure map[int]*vertex 75 | numVertices int 76 | numEdges int 77 | } 78 | 79 | func NewDALGraph() *DirectedAdjacencyListGraph { 80 | return &DirectedAdjacencyListGraph{ 81 | make(map[int]*vertex), 82 | 0, 83 | 0, 84 | } 85 | } 86 | 87 | // NumVertices returns the total number of vertices currently in the graph. 88 | func (dalg *DirectedAdjacencyListGraph) NumVertices() int { 89 | return dalg.numVertices 90 | } 91 | 92 | // NumEdges returns the total number of edges currently in the graph. 93 | func (dalg *DirectedAdjacencyListGraph) NumEdges() int { 94 | return dalg.numEdges 95 | } 96 | 97 | // Edges returns a list of all the edges in the graph. 98 | func (dalg *DirectedAdjacencyListGraph) Edges() []*edge { 99 | var edges = make([]*edge, dalg.numEdges) 100 | for _, v := range dalg.primaryStructure { 101 | edges = append(edges, v.outgoingEdges...) 102 | } 103 | 104 | return edges 105 | } 106 | 107 | // Edges returns a list of all the edges in the graph 108 | func (dalg *DirectedAdjacencyListGraph) Vertices() []*vertex { 109 | var vertices = make([]*vertex, dalg.numVertices) 110 | for _, v := range dalg.primaryStructure { 111 | vertices = append(vertices, v) 112 | } 113 | 114 | return vertices 115 | } 116 | 117 | // GetEdge returns the `edge` that start from `fromVertex` and ends at `toVertex` 118 | // if one exists; otherwise return null. 119 | // 120 | // ARGUMENTS 121 | // 122 | // fromVertex (vertex): the vertex this edge starts from. The outgoing vertex. 123 | // toVertex (vertex): the vertex this edge is incident on. The incoming vertex. 124 | func (dalg *DirectedAdjacencyListGraph) GetEdge(fromVertexID, toVertexID int) *edge { 125 | fromVertex := dalg.primaryStructure[fromVertexID] 126 | toVertex := dalg.primaryStructure[toVertexID] 127 | if fromVertex != nil && toVertex != nil { 128 | for _, e := range fromVertex.outgoingEdges { 129 | if e.toVertex == toVertex { 130 | return e 131 | } 132 | } 133 | } 134 | 135 | return nil 136 | } 137 | 138 | // OutDegree returns the number of outgoing edges from vertex with the specified ID. 139 | // 140 | // ARGUMENTS 141 | // 142 | // id (int): ID of the vertex of interest 143 | func (dalg *DirectedAdjacencyListGraph) OutDegree(id int) int { 144 | if dalg.primaryStructure[id] != nil { 145 | return len(dalg.primaryStructure[id].outgoingEdges) 146 | } 147 | 148 | return -1 149 | } 150 | 151 | // InDegree returns the number of outgoing edges from vertex with the specified ID. 152 | // 153 | // ARGUMENTS 154 | // 155 | // id (int): ID of the vertex of interest 156 | func (dalg *DirectedAdjacencyListGraph) InDegree(id int) int { 157 | if dalg.primaryStructure[id] != nil { 158 | return len(dalg.primaryStructure[id].incomingEdges) 159 | } 160 | 161 | return -1 162 | } 163 | 164 | // OutgoingEdges Returns a list of all outgoing edges from vertex with the specified ID. 165 | // 166 | // ARGUMENTS 167 | // 168 | // id (int): ID of the vertex of interest 169 | func (dalg *DirectedAdjacencyListGraph) OutgoingEdges(id int) []*edge { 170 | if dalg.primaryStructure[id] != nil { 171 | return dalg.primaryStructure[id].outgoingEdges 172 | } 173 | 174 | return nil 175 | } 176 | 177 | // IncomingEdges Returns a list of all outgoing edges from vertex with the specified ID. 178 | // 179 | // ARGUMENTS 180 | // 181 | // id (int): ID of the vertex of interest 182 | func (dalg *DirectedAdjacencyListGraph) IncomingEdges(id int) []*edge { 183 | if dalg.primaryStructure[id] != nil { 184 | return dalg.primaryStructure[id].outgoingEdges 185 | } 186 | 187 | return nil 188 | } 189 | 190 | // InsertVertex Creates and returns a new Vertex storing element `item`. 191 | // 192 | // ARGUMENTS 193 | // item (interface): the item the vertex will hold. 194 | func (dalg *DirectedAdjacencyListGraph) InsertVertex(item interface{}) *vertex { 195 | if item != nil { 196 | v := &vertex{ 197 | dalg.numVertices, 198 | item, 199 | make([]*edge, 0), 200 | make([]*edge, 0), 201 | } 202 | dalg.primaryStructure[dalg.numVertices] = v 203 | dalg.numVertices++ 204 | 205 | return v 206 | } 207 | 208 | return nil 209 | } 210 | 211 | // InsertEdge Creates and returns a new Edge from vertex `fromVertex` to vertex `toVertex`, 212 | // storing element x; an error occurs if there already exists an edge from `fromVertex` to `toVertex` 213 | // 214 | // ARGUMENTS 215 | // 216 | // fromVertex (vertex): the vertex this edge starts from. The outgoing vertex. 217 | // toVertex (vertex): the vertex this edge is incident on. The incoming vertex. 218 | // item (interface): the item the edge will hold (in the case of a weighted graph). 219 | func (dalg *DirectedAdjacencyListGraph) InsertEdge(fromVertexID, toVertexID int, item interface{}) interface{} { 220 | if dalg.GetEdge(fromVertexID, toVertexID) == nil { 221 | fromVertex := dalg.primaryStructure[fromVertexID] 222 | toVertex := dalg.primaryStructure[toVertexID] 223 | if fromVertex != nil && toVertex != nil { 224 | e := &edge{ 225 | dalg.numEdges, 226 | item, 227 | fromVertex, 228 | toVertex, 229 | } 230 | 231 | fromVertex.outgoingEdges = append(fromVertex.outgoingEdges, e) 232 | toVertex.incomingEdges = append(toVertex.incomingEdges, e) 233 | 234 | dalg.numEdges++ 235 | 236 | return e 237 | } 238 | } 239 | 240 | return nil 241 | } 242 | 243 | // RemoveVertex Removes vertex with the specified ID and all its incident edges from the graph. 244 | // 245 | // ARGUMENTS 246 | // 247 | // id (int): ID of the vertex of interest 248 | func (dalg *DirectedAdjacencyListGraph) RemoveVertex(id int) bool { 249 | if dalg.primaryStructure[id] != nil { 250 | delete(dalg.primaryStructure, id) 251 | dalg.numVertices-- 252 | 253 | return true 254 | } 255 | 256 | return false 257 | } 258 | 259 | // RemoveEdge removes edge e from the graph. 260 | // 261 | // ARGUMENTS 262 | // 263 | // e (edge): the edge to be removed 264 | func (dalg *DirectedAdjacencyListGraph) RemoveEdge(e *edge) bool { 265 | if e != nil && e.id >= 0 && e.id < len(e.fromVertex.outgoingEdges) { 266 | 267 | e.fromVertex.outgoingEdges[e.id] = e.fromVertex.outgoingEdges[len(e.fromVertex.outgoingEdges)-1] 268 | e.fromVertex.outgoingEdges = e.fromVertex.outgoingEdges[:len(e.fromVertex.outgoingEdges)-1] 269 | 270 | e.toVertex.incomingEdges[e.id] = e.toVertex.incomingEdges[len(e.toVertex.incomingEdges)-1] 271 | e.toVertex.incomingEdges = e.toVertex.incomingEdges[:len(e.toVertex.incomingEdges)-1] 272 | 273 | dalg.numEdges-- 274 | 275 | return true 276 | } 277 | 278 | return false 279 | } 280 | 281 | // Performs a Generic Breadth-First Search on the graph. All is does is 282 | // return a list of the IDs of the nodes in the order they were visited. 283 | // 284 | // Example: [4, 2, 0, 3, 1] 285 | func (dalg *DirectedAdjacencyListGraph) BFS() []int { 286 | var l []int 287 | visitedTable := make(map[int]bool, dalg.numVertices) 288 | for key := range dalg.primaryStructure { 289 | visitedTable[key] = false 290 | } 291 | 292 | for key, vertex := range dalg.primaryStructure { 293 | if !visitedTable[key] { 294 | l = bfs(vertex, visitedTable) 295 | } 296 | } 297 | 298 | return l 299 | } 300 | 301 | func bfs(v *vertex, visitedTable map[int]bool) []int { 302 | l := make([]int, 0) 303 | queue := queuestack.NewQueue() 304 | queue.Enqueue(v) 305 | visitedTable[v.id] = true 306 | 307 | l = append(l, v.id) 308 | 309 | for !queue.Empty() { 310 | if node, err := queue.Dequeue(); err == nil { 311 | for _, ed := range node.(*vertex).outgoingEdges { 312 | if !visitedTable[ed.toVertex.id] { 313 | visitedTable[ed.toVertex.id] = true 314 | queue.Enqueue(ed.toVertex) 315 | 316 | l = append(l, ed.toVertex.id) 317 | } 318 | } 319 | } 320 | } 321 | 322 | return l 323 | } 324 | -------------------------------------------------------------------------------- /adjaceny-list-graph/adjacency-list-graph_test.go: -------------------------------------------------------------------------------- 1 | package adjaceny_list_graph 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | // Setup 8 | var dalg = NewDALGraph() 9 | 10 | func TestDirectedAdjacencyListGraph_NumEdges(t *testing.T) { 11 | if dalg.numEdges != 0 { 12 | t.Errorf("Incorrect, got: %d, expected: %d.", dalg.numEdges, 0) 13 | } 14 | } 15 | 16 | func TestDirectedAdjacencyListGraph_NumVertices(t *testing.T) { 17 | if dalg.numVertices != 0 { 18 | t.Errorf("Incorrect, got: %d, expected: %d.", dalg.numVertices, 0) 19 | } 20 | } 21 | 22 | func TestDirectedAdjacencyListGraph_InsertVertex(t *testing.T) { 23 | v := dalg.InsertVertex("thor") 24 | if v.item != "thor" { 25 | t.Errorf("Incorrect, got: %d, expected: %s.", v.item, "thor") 26 | } 27 | 28 | v = dalg.InsertVertex("loki") 29 | if v.item != "loki" { 30 | t.Errorf("Incorrect, got: %d, expected: %s.", v.item, "loki") 31 | } 32 | 33 | v = dalg.InsertVertex(nil) 34 | if v != nil { 35 | t.Errorf("Incorrect, got: %d, expected: %v.", v, nil) 36 | } 37 | 38 | if dalg.numVertices != 2 { 39 | t.Errorf("Incorrect, got: %d, expected: %v.", dalg.numVertices, 1) 40 | } 41 | } 42 | 43 | func TestDirectedAdjacencyListGraph_InsertEdge(t *testing.T) { 44 | e := dalg.InsertEdge(0, 1, "brother") 45 | if e.(*edge).weight != "brother" { 46 | t.Errorf("Incorrect, got: %d, expected: %v.", e.(edge).weight, "brother") 47 | } 48 | 49 | if dalg.numEdges != 1 { 50 | t.Errorf("Incorrect, got: %d, expected: %v.", dalg.numEdges, 1) 51 | } 52 | 53 | if dalg.primaryStructure[0].outgoingEdges[0].weight != "brother" || 54 | dalg.primaryStructure[1].incomingEdges[0].weight != "brother" { 55 | 56 | t.Error("edge between vertex 0 and 1 broken") 57 | } 58 | 59 | e = dalg.InsertEdge(1, 4, "brother") 60 | if e != nil { 61 | t.Error("Incorrect, should be nil") 62 | } 63 | 64 | e = dalg.InsertEdge(0, 1, "brother") 65 | if e != nil { 66 | t.Error("Incorrect, should be nil. Edge already exist") 67 | } 68 | } 69 | 70 | func TestDirectedAdjacencyListGraph_GetEdge(t *testing.T) { 71 | e := dalg.GetEdge(0, 1) 72 | if e == nil { 73 | t.Error("Incorrect. Edge actually exist") 74 | } 75 | 76 | if e.weight != "brother" { 77 | t.Errorf("Incorrect, got: %d, expected: %v.", e.weight, "brother") 78 | } 79 | 80 | e = dalg.GetEdge(1, 4) 81 | if e != nil { 82 | t.Error("Incorrect. Edge DOES NOT actually exist. e should be nil") 83 | } 84 | } 85 | 86 | func TestDirectedAdjacencyListGraph_RemoveEdge(t *testing.T) { 87 | e := dalg.GetEdge(0, 1) 88 | if e == nil { 89 | t.Error("Incorrect. Edge actually exist") 90 | } 91 | 92 | dalg.RemoveEdge(e) 93 | 94 | e = dalg.GetEdge(0, 1) 95 | if e != nil { 96 | t.Error("Incorrect. Edge does not exist. Should be nil") 97 | } 98 | 99 | if dalg.numEdges != 0 { 100 | t.Errorf("Incorrect, got: %d, expected: %v.", dalg.numEdges, 0) 101 | } 102 | 103 | e = dalg.GetEdge(1, 4) 104 | if e != nil { 105 | t.Error("Incorrect. Edge DOES NOT actually exist. e should be nil") 106 | } 107 | 108 | if dalg.RemoveEdge(e) { 109 | t.Error("Incorrect. Edge DOES NOT actually exist.") 110 | } 111 | 112 | if dalg.RemoveEdge(NewEdge()) { 113 | t.Error("Incorrect. Edge DOES NOT actually exist.") 114 | } 115 | } 116 | 117 | func TestDirectedAdjacencyListGraph_RemoveVertex(t *testing.T) { 118 | dalg.RemoveVertex(0) 119 | if dalg.numVertices != 1 { 120 | t.Errorf("Incorrect, got: %d, expected: %v.", dalg.numVertices, 1) 121 | } 122 | 123 | if dalg.RemoveVertex(0) { 124 | t.Error("Incorrect. Vertex DOES NOT actually exist.") 125 | } 126 | } 127 | 128 | func TestIntegration(t *testing.T) { 129 | // Create a new graph 130 | g := NewDALGraph() 131 | 132 | // Insert all the vertices 133 | v1 := g.InsertVertex(1) 134 | v2 := g.InsertVertex(2) 135 | v3 := g.InsertVertex(3) 136 | v4 := g.InsertVertex(4) 137 | v5 := g.InsertVertex(5) 138 | 139 | // Insert all the edges 140 | e12 := g.InsertEdge(v1.id, v2.id, "12") 141 | g.InsertEdge(v1.id, v4.id, "14") 142 | g.InsertEdge(v3.id, v1.id, "31") 143 | e34 := g.InsertEdge(v3.id, v4.id, "34") 144 | g.InsertEdge(v4.id, v5.id, "45") 145 | g.InsertEdge(v5.id, v3.id, "53") 146 | 147 | e912 := g.InsertEdge(9, 12, "912") 148 | if e912 != nil { 149 | t.Errorf("Incorrect, cannot insert such edge") 150 | } 151 | 152 | // Checking for the number of edges and vertices 153 | if g.NumVertices() != 5 { 154 | t.Errorf("Incorrect, got: %d, expected: %v.", g.NumVertices(), 5) 155 | } 156 | if g.NumEdges() != 6 { 157 | t.Errorf("Incorrect, got: %d, expected: %v.", g.NumEdges(), 6) 158 | } 159 | 160 | // Testing GetEdge() 161 | e := g.GetEdge(v1.id, v2.id) 162 | if e.id != e12.(*edge).id { 163 | t.Errorf("Incorrect, got: %d, expected: %v.", e.id, e12.(*edge).id) 164 | } 165 | if e.weight != e12.(*edge).weight { 166 | t.Errorf("Incorrect, got: %d, expected: %v.", e.weight, e12.(*edge).weight) 167 | } 168 | 169 | e = g.GetEdge(v3.id, v4.id) 170 | if e.id != e34.(*edge).id { 171 | t.Errorf("Incorrect, got: %d, expected: %v.", e.id, e34.(*edge).id) 172 | } 173 | if e.weight != e34.(*edge).weight { 174 | t.Errorf("Incorrect, got: %d, expected: %v.", e.weight, e34.(*edge).weight) 175 | } 176 | 177 | e = g.GetEdge(5, 3) 178 | if e != nil { 179 | t.Error("Incorrect. That edge is invalid") 180 | } 181 | 182 | // Testing OutDegree 183 | if g.OutDegree(v1.id) != 2 { 184 | t.Errorf("Incorrect, got: %d, expected: %v.", g.OutDegree(v1.id), 2) 185 | } 186 | if g.OutDegree(v3.id) != 2 { 187 | t.Errorf("Incorrect, got: %d, expected: %v.", g.OutDegree(v3.id), 2) 188 | } 189 | if g.OutDegree(v5.id) != 1 { 190 | t.Errorf("Incorrect, got: %d, expected: %v.", g.OutDegree(v5.id), 1) 191 | } 192 | if g.OutDegree(9) != -1 { 193 | t.Errorf("Incorrect, got: %d, expected: %v.", g.OutDegree(9), -1) 194 | } 195 | 196 | // Testing InDegree 197 | if g.InDegree(v4.id) != 2 { 198 | t.Errorf("Incorrect, got: %d, expected: %v.", g.InDegree(v4.id), 2) 199 | } 200 | if g.InDegree(v3.id) != 1 { 201 | t.Errorf("Incorrect, got: %d, expected: %v.", g.InDegree(v3.id), 1) 202 | } 203 | if g.InDegree(v2.id) != 1 { 204 | t.Errorf("Incorrect, got: %d, expected: %v.", g.InDegree(v2.id), 1) 205 | } 206 | if g.InDegree(9) != -1 { 207 | t.Errorf("Incorrect, got: %d, expected: %v.", g.InDegree(9), -1) 208 | } 209 | 210 | // Testing Breadth-First Search 211 | t.Log(g.BFS()) 212 | } 213 | -------------------------------------------------------------------------------- /allpairs/allpairs.go: -------------------------------------------------------------------------------- 1 | // This package provide a algorithm for distance of all pairs problems 2 | // It solves this problem with Floyd-Warshall algorithm in O(N^3) 3 | package allpairs 4 | 5 | // Max Integer 6 | const INF = int(^uint(0) >> 2) 7 | 8 | // Type for edge data - endpoints u, v and length 9 | type Edge struct { 10 | u, v, length int 11 | } 12 | 13 | type Edges []Edge 14 | 15 | func (edges Edges) Swap(i, j int) { 16 | edges[i], edges[j] = edges[j], edges[i] 17 | } 18 | 19 | func (edges Edges) Len() int { 20 | return len(edges) 21 | } 22 | 23 | func (edges Edges) Less(i, j int) bool { 24 | return edges[i].length < edges[j].length 25 | } 26 | 27 | // Computes the distance of all pairs 28 | func allPairsDistance(n int, edges []Edge) [][]int { 29 | distance := make([][]int, n) 30 | for i := range distance { 31 | distance[i] = make([]int, n) 32 | } 33 | 34 | for i := 0; i < n; i++ { 35 | for j := 0; j < n; j++ { 36 | distance[i][j] = INF 37 | } 38 | } 39 | 40 | for _, edge := range edges { 41 | if distance[edge.u][edge.v] > edge.length { 42 | distance[edge.u][edge.v] = edge.length 43 | } 44 | } 45 | 46 | for i := 0; i < n; i++ { 47 | distance[i][i] = 0 48 | } 49 | 50 | for k := 0; k < n; k++ { 51 | for i := 0; i < n; i++ { 52 | for j := 0; j < n; j++ { 53 | if distance[i][j] > distance[i][k]+distance[k][j] { 54 | distance[i][j] = distance[i][k] + distance[k][j] 55 | } 56 | } 57 | } 58 | } 59 | 60 | return distance 61 | } 62 | -------------------------------------------------------------------------------- /allpairs/allpairs_test.go: -------------------------------------------------------------------------------- 1 | package allpairs 2 | 3 | import "testing" 4 | 5 | // Tests the Floyd Warshall all pairs algorithm 6 | func TestAllPairs(t *testing.T) { 7 | edges := []Edge{{4, 5, 10}} 8 | 9 | for i := 0; i < 3; i++ { 10 | for j := i + 1; j < 3; j++ { 11 | edges = append(edges, Edge{i, j, j - i}) 12 | } 13 | } 14 | 15 | // For the given test the answer has cost 13 and is unique 16 | 17 | distance := allPairsDistance(6, edges) 18 | 19 | if len(distance) != 6 { 20 | t.Error("Returned array of distance have wrong size") 21 | } 22 | 23 | if distance[4][5] != 10 { 24 | t.Error("Distance from 4 to 5 is wrong") 25 | } 26 | 27 | if distance[1][5] != INF { 28 | t.Error("Distance from 1 to 5 is wrong") 29 | } 30 | 31 | if distance[1][2] != 1 { 32 | t.Error("Distance from 1 to 2 is wrong") 33 | } 34 | 35 | if distance[3][3] != 0 { 36 | t.Error("Distance from 3 to 3 is wrong") 37 | } 38 | 39 | if distance[3][5] != INF { 40 | t.Error("Distance from 3 to 4 is wrong") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /bst/binarySearchTree.go: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import ( 4 | "fmt" //importing required packages 5 | ) 6 | 7 | type Node struct { //Node represents node of a Binary Search Tree 8 | value int 9 | left *Node 10 | right *Node 11 | } 12 | 13 | func Insert(root *Node, key int) *Node { //The following function inserts elements into Binary Search Tree 14 | if root == nil { 15 | root = &Node{key, nil, nil} //root node is created with left and right child as nil 16 | } else if key < root.value { 17 | root.left = Insert(root.left, key) //Using recursion to maintain the tree as BST 18 | } else if key > root.value { 19 | root.right = Insert(root.right, key) 20 | } 21 | return root 22 | } 23 | 24 | func Search(root *Node, key int) *Node { //The following function searches a given key in a BST 25 | if root == nil { 26 | return root 27 | } 28 | 29 | if root.value == key { //If the key is not found a nil pointer is returned 30 | return root 31 | } 32 | if root.value < key { 33 | return Search(root.right, key) 34 | } 35 | return Search(root.left, key) 36 | 37 | } 38 | func Minval(root *Node) *Node { //The following function is used in Delete function to find the inorder successor 39 | var current *Node 40 | current = root 41 | for current.left != nil { 42 | current = current.left 43 | } 44 | return current 45 | } 46 | func Delete(root *Node, key int) *Node { //The following function deletes the key in BST and returns the new root 47 | if root == nil { 48 | //base case 49 | return root 50 | } 51 | if key < root.value { //If the key to be deleted is smaller than the root's key,the key lies in the left subtree 52 | root.left = Delete(root.left, key) 53 | } else if key > root.value { //If the key to be deleted is greater than the root's key,the key lies in the right subtree 54 | root.right = Delete(root.right, key) 55 | } else { //node with only one child 56 | if root.left == nil { 57 | var temp *Node = root.right 58 | return temp 59 | } else if root.right == nil { 60 | var temp *Node = root.left 61 | return temp 62 | } //node with two children 63 | var temp *Node 64 | temp = Minval(root.right) //Get inorder successor 65 | root.value = temp.value //Get the inorder successor's value 66 | root.right = Delete(root.right, temp.value) //Delete the inorder successor 67 | } 68 | return root 69 | } 70 | func PreorderTraverse(root *Node) { //The following function does preorder traversal of BST,i.e,Root,left,Right nodes. 71 | if root == nil { 72 | return 73 | } 74 | fmt.Println(root.value) 75 | PreorderTraverse(root.left) 76 | PreorderTraverse(root.right) 77 | } 78 | 79 | func InorderTraverse(root *Node) { //The following function does inorder traversal of BST,i.e,Left,Root,Right nodes. 80 | if root == nil { 81 | return 82 | } 83 | InorderTraverse(root.left) 84 | fmt.Println(root.value) 85 | InorderTraverse(root.right) 86 | } 87 | 88 | func PostorderTraverse(root *Node) { //The following function does postorder traversal of BST,i.e,Left,Right,Root nodes. 89 | if root == nil { 90 | return 91 | } 92 | PostorderTraverse(root.left) 93 | PostorderTraverse(root.right) 94 | fmt.Println(root.value) 95 | } 96 | func IdenticalTrees(a *Node, b *Node) bool { //The following function checks whether two trees are indentical or not 97 | if a == nil && b == nil { 98 | return true 99 | } 100 | if a != nil && b != nil { 101 | return (a.value == b.value && IdenticalTrees(a.left, b.left) && IdenticalTrees(a.right, b.right)) 102 | } 103 | return false 104 | } 105 | -------------------------------------------------------------------------------- /bst/binarySearchTree_test.go: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import "testing" 4 | 5 | func TestDelete(t *testing.T) { 6 | var testNode *Node 7 | testNode = Insert(testNode, 12) 8 | Insert(testNode, 1) 9 | Insert(testNode, 3) 10 | Insert(testNode, 25) 11 | 12 | var expectedNode *Node 13 | expectedNode = Insert(expectedNode, 12) 14 | Insert(expectedNode, 1) 15 | Insert(expectedNode, 3) 16 | Delete(testNode, 25) 17 | 18 | if testNode == nil { 19 | t.Error("Binary tree cannot be empty for deletion") 20 | } 21 | 22 | if IdenticalTrees(testNode, expectedNode) == false { 23 | t.Error("Deletion has not taken place") 24 | } 25 | 26 | } 27 | func TestSearch(t *testing.T) { 28 | var testNode *Node 29 | testNode = Insert(testNode, 12) 30 | Insert(testNode, 1) 31 | Insert(testNode, 3) 32 | Insert(testNode, 25) 33 | if Search(testNode, 3) == nil { 34 | t.Error("This is incorrect since the number is present in BST") 35 | } 36 | } 37 | 38 | func TestInsert(t *testing.T) { 39 | var testNode *Node 40 | testNode = Insert(testNode, 12) 41 | Insert(testNode, 1) 42 | Insert(testNode, 3) 43 | Insert(testNode, 25) 44 | 45 | if testNode == nil { 46 | t.Error("The elements haven't been inserted into the bst") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /btree/btree.go: -------------------------------------------------------------------------------- 1 | package btree 2 | 3 | //Index interface of data container of Node 4 | type Index interface { 5 | LessThan(Index) bool 6 | EqualsTo(Index) bool 7 | } 8 | 9 | //Node Tree element struct 10 | type Node struct { 11 | Data Index 12 | Score int 13 | Edges [2]*Node 14 | } 15 | 16 | // Public 17 | 18 | // Insert a node into the AVL tree. 19 | func Insert(tree **Node, data Index) { 20 | *tree, _ = insertInRightOf(*tree, data) 21 | } 22 | 23 | // Remove a single item from an AVL tree. 24 | func Remove(tree **Node, data Index) { 25 | *tree, _ = removeFromRightOf(*tree, data) 26 | } 27 | 28 | // Private 29 | 30 | func opp(d int) int { 31 | return 1 - d 32 | } 33 | 34 | //singleRotation 35 | func singleRotation(parent *Node, direction int) (b *Node) { 36 | b = parent.Edges[opp(direction)] 37 | parent.Edges[opp(direction)] = b.Edges[direction] 38 | b.Edges[direction] = parent 39 | return 40 | } 41 | 42 | //doubleRotation 43 | func doubleRotation(parent *Node, d int) (b *Node) { 44 | b = parent.Edges[opp(d)].Edges[d] 45 | parent.Edges[opp(d)].Edges[d] = b.Edges[opp(d)] 46 | b.Edges[opp(d)] = parent.Edges[opp(d)] 47 | parent.Edges[opp(d)] = b 48 | 49 | b = parent.Edges[opp(d)] 50 | parent.Edges[opp(d)] = b.Edges[d] 51 | b.Edges[d] = parent 52 | return 53 | } 54 | 55 | func adjust(parent *Node, dir, bal int) { 56 | n := parent.Edges[dir] 57 | nn := n.Edges[opp(dir)] 58 | switch nn.Score { 59 | case 0: 60 | parent.Score = 0 61 | n.Score = 0 62 | case bal: 63 | parent.Score = bal 64 | n.Score = 0 65 | default: 66 | parent.Score = 0 67 | n.Score = bal 68 | } 69 | nn.Score = 0 70 | } 71 | 72 | func insertScoreBalance(node *Node, dir int) *Node { 73 | n := node.Edges[dir] 74 | bal := 2*dir - 1 75 | if n.Score == bal { 76 | node.Score = 0 77 | n.Score = 0 78 | return singleRotation(node, opp(dir)) 79 | } 80 | adjust(node, dir, bal) 81 | return doubleRotation(node, opp(dir)) 82 | } 83 | 84 | //insertInRightOf 85 | func insertInRightOf(node *Node, data Index) (*Node, bool) { 86 | if node == nil { 87 | return &Node{Data: data}, false 88 | } 89 | dir := 0 90 | if node.Data.LessThan(data) { 91 | dir = 1 92 | } 93 | var done bool 94 | node.Edges[dir], done = insertInRightOf(node.Edges[dir], data) 95 | if done { 96 | return node, true 97 | } 98 | node.Score += 2*dir - 1 99 | switch node.Score { 100 | case 0: 101 | return node, true 102 | case 1, -1: 103 | return node, false 104 | } 105 | return insertScoreBalance(node, dir), true 106 | } 107 | 108 | //removeScoreBalance 109 | func removeScoreBalance(root *Node, dir int) (*Node, bool) { 110 | n := root.Edges[opp(dir)] 111 | bal := 2*dir - 1 112 | switch n.Score { 113 | case -bal: 114 | root.Score = 0 115 | n.Score = 0 116 | return singleRotation(root, dir), false 117 | case bal: 118 | adjust(root, opp(dir), -bal) 119 | return doubleRotation(root, dir), false 120 | } 121 | root.Score = -bal 122 | n.Score = bal 123 | return singleRotation(root, dir), true 124 | } 125 | 126 | //removeFromRightOf 127 | func removeFromRightOf(node *Node, data Index) (*Node, bool) { 128 | if node == nil { 129 | return nil, false 130 | } 131 | if node.Data.EqualsTo(data) { 132 | switch { 133 | case node.Edges[0] == nil: 134 | return node.Edges[1], false 135 | case node.Edges[1] == nil: 136 | return node.Edges[0], false 137 | } 138 | heir := node.Edges[0] 139 | for heir.Edges[1] != nil { 140 | heir = heir.Edges[1] 141 | } 142 | node.Data = heir.Data 143 | data = heir.Data 144 | } 145 | dir := 0 146 | if node.Data.LessThan(data) { 147 | dir = 1 148 | } 149 | var done bool 150 | node.Edges[dir], done = removeFromRightOf(node.Edges[dir], data) 151 | if done { 152 | return node, true 153 | } 154 | node.Score += 1 - 2*dir 155 | switch node.Score { 156 | case 1, -1: 157 | return node, true 158 | case 0: 159 | return node, false 160 | } 161 | return removeScoreBalance(node, dir) 162 | } 163 | -------------------------------------------------------------------------------- /btree/btree_test.go: -------------------------------------------------------------------------------- 1 | package btree 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | type integerIndex int 10 | 11 | func (ii integerIndex) LessThan(ii2 Index) bool { 12 | return ii < ii2.(integerIndex) 13 | } 14 | func (ii integerIndex) EqualsTo(ii2 Index) bool { 15 | return ii == ii2.(integerIndex) 16 | } 17 | 18 | //TestBtree 19 | func TestBtree(t *testing.T) { 20 | var tree *Node 21 | fmt.Println("Empty Tree:") 22 | balancedTreeJson, _ := json.MarshalIndent(tree, "", "--") 23 | 24 | fmt.Println("\nInsert Tree:") 25 | Insert(&tree, integerIndex(4)) 26 | if tree.Score != 4 { 27 | t.Fatalf("Score should be 4, got %v", tree.Score) 28 | } 29 | Insert(&tree, integerIndex(3)) 30 | Insert(&tree, integerIndex(8)) 31 | if tree.Score != 4 { 32 | t.Fatalf("Score should be 4, got %v", tree.Score) 33 | } 34 | Insert(&tree, integerIndex(6)) 35 | Insert(&tree, integerIndex(7)) 36 | Insert(&tree, integerIndex(9)) 37 | if tree.Score != 6 { 38 | t.Fatalf("Score should be 6, got %v", tree.Score) 39 | } 40 | balancedTreeJson, _ = json.MarshalIndent(tree, "", "--") 41 | fmt.Println(string(balancedTreeJson)) 42 | 43 | fmt.Println("\nRemove Tree:") 44 | Remove(&tree, integerIndex(4)) 45 | Remove(&tree, integerIndex(6)) 46 | balancedTreeJson, _ = json.MarshalIndent(tree, "", "--") 47 | fmt.Println(string(balancedTreeJson)) 48 | } 49 | -------------------------------------------------------------------------------- /bubblesort/bubblesort.go: -------------------------------------------------------------------------------- 1 | // Package bubblesort provides implementation for bubble sort algorithm 2 | package bubblesort 3 | 4 | // Swap function changes two integers 5 | func Swap(lhs *int, rhs *int) { 6 | tmp := *lhs 7 | *lhs = *rhs 8 | *rhs = tmp 9 | } 10 | 11 | // Bubblesort function receives an array and return the sorted array 12 | // O(N^2) 13 | func bubbleSort(A []int) []int { 14 | N := len(A) 15 | result := make([]int, len(A)) 16 | i := 0 17 | j := 0 18 | for i = 0; i < N; i++ { 19 | result[i] = A[i] 20 | } 21 | 22 | for i = 0; i < N-1; i++ { 23 | for j = 0; j < N-1; j++ { 24 | if result[j] > result[j+1] { 25 | Swap(&result[j], &result[j+1]) 26 | } 27 | } 28 | } 29 | return result 30 | } 31 | -------------------------------------------------------------------------------- /bubblesort/bubblesort_test.go: -------------------------------------------------------------------------------- 1 | package bubblesort 2 | 3 | 4 | import ( 5 | "math/rand" 6 | "reflect" 7 | "sort" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | // TestBubbleSort inspired in mergesort_test 13 | func TestBubbleSort(t *testing.T) { 14 | empty := []int{} 15 | resultEmpty := bubbleSort(empty) 16 | 17 | if !reflect.DeepEqual(empty, resultEmpty) { 18 | t.Error("ERROR!", "Expected:", empty, "Result:", resultEmpty) 19 | return 20 | } 21 | 22 | unitary := []int{42} 23 | resultUnitary := bubbleSort(unitary) 24 | 25 | if !reflect.DeepEqual(unitary, resultUnitary) { 26 | t.Error("ERROR!", "Expected:", unitary, "Result:", resultUnitary) 27 | return 28 | } 29 | 30 | rand.Seed(int64(time.Now().Nanosecond())) 31 | for test := 0; test < 10; test++ { 32 | array := make([]int, 100) 33 | for i := 0; i < 100; i++ { 34 | array[i] = rand.Int() 35 | } 36 | 37 | expected := make([]int, 100) 38 | copy(expected, array) 39 | sort.Ints(expected) 40 | 41 | result := bubbleSort(array) 42 | 43 | if !reflect.DeepEqual(result, expected) { 44 | t.Error("ERROR!", "Expected:", expected, "Result:", result) 45 | return 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /convexHull/convexHull.go: -------------------------------------------------------------------------------- 1 | // Package convexHull provides an algotithm for finding a convex hull from a 2 | // set of point. Implemented algorithm: 3 | // https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain 4 | package convexHull 5 | 6 | import "sort" 7 | 8 | // Point is a struct that holds the X Y cooridinates 9 | // of a specific point in the Ecliden plane or space. 10 | type Point struct { 11 | X, Y int 12 | } 13 | 14 | // Points is a slice built up of Point structs. 15 | type Points []Point 16 | 17 | func (points Points) Swap(i, j int) { 18 | points[i], points[j] = points[j], points[i] 19 | } 20 | 21 | func (points Points) Len() int { 22 | return len(points) 23 | } 24 | 25 | // lets sort our Points by x and, if equal, by y 26 | func (points Points) Less(i, j int) bool { 27 | if points[i].X == points[j].X { 28 | return points[i].Y < points[j].Y 29 | } 30 | return points[i].X < points[j].X 31 | } 32 | 33 | // returns the modulo (and sign) of the cross product between vetors OA and OB 34 | func crossProduct(O, A, B Point) int { 35 | return (A.X-O.X)*(B.Y-O.Y) - (A.Y-O.Y)*(B.X-O.X) 36 | } 37 | 38 | // findConvexHull returns a slice of Point with a convex hull 39 | // it is counterclockwise and starts and ends at the same point 40 | // i.e. the same point is repeated at the beginning and at the end 41 | func findConvexHull(points Points) Points { 42 | n := len(points) // number of points to find convex hull 43 | var result Points // final result 44 | count := 0 // size of our convex hull (number of points added) 45 | 46 | // lets sort our points by x and if equal by y 47 | sort.Sort(points) 48 | 49 | if n == 0 { 50 | return result 51 | } 52 | 53 | // add the first element: 54 | result = append(result, points[0]) 55 | count++ 56 | 57 | // find the lower hull 58 | for i := 1; i < n; i++ { 59 | // remove points which are not part of the lower hull 60 | for count > 1 && crossProduct(result[count-2], result[count-1], points[i]) < 0 { 61 | count-- 62 | result = result[:count] 63 | } 64 | 65 | // add a new better point than the removed ones 66 | result = append(result, points[i]) 67 | count++ 68 | } 69 | 70 | count0 := count // our base counter for the upper hull 71 | 72 | // find the upper hull 73 | for i := n - 2; i >= 0; i-- { 74 | // remove points which are not part of the upper hull 75 | for count-count0 > 0 && crossProduct(result[count-2], result[count-1], points[i]) < 0 { 76 | count-- 77 | result = result[:count] 78 | } 79 | 80 | // add a new better point than the removed ones 81 | result = append(result, points[i]) 82 | count++ 83 | } 84 | 85 | return result 86 | } 87 | -------------------------------------------------------------------------------- /convexHull/convexHull_test.go: -------------------------------------------------------------------------------- 1 | package convexHull 2 | 3 | import "testing" 4 | 5 | func TestConvexHull(t *testing.T) { 6 | var points = Points{{0, 3}, {2, 2}, {1, 1}, {2, 1}, 7 | {3, 0}, {0, 0}, {3, 3}} 8 | var expected = Points{{0, 0}, {3, 0}, {3, 3}, {0, 3}, {0, 0}} 9 | var result = findConvexHull(points) 10 | 11 | if result == nil { 12 | t.Error("returned convex hull is nil") 13 | return 14 | } 15 | 16 | if len(result) != len(expected) { 17 | t.Error("returned convex hull has a different size") 18 | return 19 | } 20 | 21 | for i := range result { 22 | if result[i] != expected[i] { 23 | t.Error("returned convex hull is wrong") 24 | return 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /doc/gopher.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch3ck/algo/5aae7fab9e3d6ebca20ee30441c232f43815b89b/doc/gopher.jpg -------------------------------------------------------------------------------- /doc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch3ck/algo/5aae7fab9e3d6ebca20ee30441c232f43815b89b/doc/logo.png -------------------------------------------------------------------------------- /graph/graph.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import "fmt" 4 | 5 | // Node 6 | type ID string 7 | 8 | type Node interface { 9 | Id() ID 10 | Edges() []ID 11 | } 12 | 13 | type node struct { 14 | id ID 15 | edges []ID 16 | } 17 | 18 | func (n node) Id() ID { 19 | return n.id 20 | } 21 | 22 | func (n node) Edges() []ID { 23 | return n.edges 24 | } 25 | 26 | // Graph 27 | type Graph interface { 28 | AddNode(id ID, edges []ID) Node 29 | BreadthFirstTraversal(start ID, visitor NodeVisitorFunc) error 30 | DepthFirstTraversal(start ID, visitor NodeVisitorFunc) error 31 | } 32 | 33 | // returning an error terminates the traversal 34 | type NodeVisitorFunc func(n Node, depth int) error 35 | 36 | type graph struct { 37 | nodes map[ID]*node 38 | } 39 | 40 | func NewDirectedGraph() Graph { 41 | return &graph{ 42 | nodes: map[ID]*node{}, 43 | } 44 | } 45 | 46 | func (g graph) AddNode(id ID, edges []ID) Node { 47 | node := &node{ 48 | id: id, 49 | edges: edges, 50 | } 51 | g.nodes[id] = node 52 | return node 53 | } 54 | 55 | // Visits each node in breadth-first order. if the visitor function returns an error 56 | // traversal is terminated and the error returned by this function. 57 | func (g graph) BreadthFirstTraversal(start ID, visitor NodeVisitorFunc) error { 58 | toVisitIds := []ID{} 59 | visitedIds := map[ID]interface{}{} 60 | 61 | depth := 0 62 | toVisitIds = append(toVisitIds, start) 63 | 64 | for len(toVisitIds) != 0 { 65 | currId := toVisitIds[0] 66 | visitedIds[currId] = nil 67 | 68 | if node := g.nodes[currId]; node != nil { 69 | if err := visitor(node, depth); err != nil { 70 | return err 71 | } 72 | for _, id := range node.edges { 73 | if _, ok := visitedIds[id]; !ok { 74 | toVisitIds = append(toVisitIds, id) 75 | } 76 | } 77 | } else { 78 | return fmt.Errorf("inconsistent graph, missing node with id %s", currId) 79 | } 80 | 81 | toVisitIds = toVisitIds[1:] 82 | } 83 | 84 | return nil 85 | } 86 | 87 | // Visits each node in depth-first order. if the visitor function returns an error 88 | // traversal is terminated and the error returned by this function. 89 | func (g graph) DepthFirstTraversal(start ID, visitor NodeVisitorFunc) error { 90 | visitedIds := map[ID]interface{}{} 91 | 92 | return g.depthFirstTraversal(start, 0, visitedIds, visitor) 93 | } 94 | 95 | func (g graph) depthFirstTraversal(currId ID, depth int, visitedIds map[ID]interface{}, visitor NodeVisitorFunc) error { 96 | curr := g.nodes[currId] 97 | if curr == nil { 98 | return fmt.Errorf("inconsistent graph or start, missing node with id %s", currId) 99 | } 100 | 101 | if err := visitor(curr, depth); err != nil { 102 | return err 103 | } 104 | visitedIds[currId] = nil 105 | 106 | for _, id := range curr.edges { 107 | if _, found := visitedIds[id]; !found { 108 | if err := g.depthFirstTraversal(id, depth+1, visitedIds, visitor); err != nil { 109 | return err 110 | } 111 | } 112 | } 113 | return nil 114 | } 115 | -------------------------------------------------------------------------------- /graph/graph_test.go: -------------------------------------------------------------------------------- 1 | package graph_test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Ch3ck/AlGo/graph" 6 | "github.com/stretchr/testify/assert" 7 | "testing" 8 | ) 9 | 10 | func TestBreadthFirstTraversal(t *testing.T) { 11 | t.Run("directed graph breadth first traversal", func(t *testing.T) { 12 | // create data 13 | g := graph.NewDirectedGraph() 14 | g.AddNode("0", []graph.ID{"1a", "1b", "1c"}) 15 | g.AddNode("1a", []graph.ID{"2a1"}) 16 | g.AddNode("1b", []graph.ID{"2b1", "2b2"}) 17 | g.AddNode("1c", []graph.ID{"2c1"}) 18 | g.AddNode("2a1", []graph.ID{"3a1"}) 19 | g.AddNode("2b1", []graph.ID{"0"}) 20 | g.AddNode("2b2", []graph.ID{"1a"}) 21 | g.AddNode("2c1", []graph.ID{"2c1"}) 22 | g.AddNode("3a1", []graph.ID{}) 23 | 24 | fmt.Printf("input: %+v\n", g) 25 | 26 | expected := []graph.ID{"0", "1a", "1b", "1c", "2a1", "2b1", "2b2", "2c1", "3a1"} 27 | actual := []graph.ID{} 28 | err := g.BreadthFirstTraversal("0", func(n graph.Node, depth int) error { 29 | actual = append(actual, n.Id()) 30 | return nil 31 | }) 32 | 33 | assert.NoError(t, err, "traversal error") 34 | assert.Equal(t, expected, actual, "traversal order failed") 35 | }) 36 | } 37 | 38 | func TestDepthFirstTraversal(t *testing.T) { 39 | t.Run("directed graph depth first traversal", func(t *testing.T) { 40 | // create data 41 | g := graph.NewDirectedGraph() 42 | g.AddNode("0", []graph.ID{"1a", "1b", "1c"}) 43 | g.AddNode("1a", []graph.ID{"2a1"}) 44 | g.AddNode("1b", []graph.ID{"2b1", "2b2"}) 45 | g.AddNode("1c", []graph.ID{"2c1"}) 46 | g.AddNode("2a1", []graph.ID{"3a1"}) 47 | g.AddNode("2b1", []graph.ID{"0", "1c"}) 48 | g.AddNode("2b2", []graph.ID{"1a"}) 49 | g.AddNode("2c1", []graph.ID{"2c1"}) 50 | g.AddNode("3a1", []graph.ID{}) 51 | 52 | fmt.Printf("input: %+v\n", g) 53 | 54 | expected := []graph.ID{"0", "1a", "2a1", "3a1", "1b", "2b1", "1c", "2c1", "2b2"} 55 | actual := []graph.ID{} 56 | err := g.DepthFirstTraversal("0", func(n graph.Node, depth int) error { 57 | actual = append(actual, n.Id()) 58 | return nil 59 | }) 60 | 61 | assert.NoError(t, err, "traversal error") 62 | assert.Equal(t, expected, actual, "traversal order failed") 63 | }) 64 | } 65 | -------------------------------------------------------------------------------- /heapsort/heapsort.go: -------------------------------------------------------------------------------- 1 | package heapsort 2 | 3 | /*import "os" 4 | import "strconv" 5 | import "fmt"*/ 6 | 7 | //Heapsort for integers in Golang 8 | //based on Professor Mark Allen Weiss' solution in C 9 | //http://users.cs.fiu.edu/~weiss/ 10 | 11 | func Swap(lhs *int, rhs *int) { 12 | tmp := *lhs 13 | *lhs = *rhs 14 | *rhs = tmp 15 | } 16 | 17 | func LeftChild(in int) (out int) { 18 | out = 2*in + 1 19 | return 20 | } 21 | 22 | func PercDown(A []int, i int, N int) { 23 | var Child int 24 | var Tmp int 25 | 26 | for Tmp = A[i]; LeftChild(i) < N; i = Child { 27 | Child = LeftChild(i) 28 | if Child != N-1 && A[Child+1] > A[Child] { 29 | Child++ 30 | } 31 | if Tmp < A[Child] { 32 | A[i] = A[Child] 33 | } else { 34 | break 35 | } 36 | } 37 | A[i] = Tmp 38 | } 39 | 40 | func Heapsort(A []int, N int) ([]int, int) { 41 | i := N 42 | for i = N / 2; i >= 0; i-- { //Build Heap 43 | PercDown(A, i, N) 44 | } 45 | 46 | for i = N - 1; i > 0; i-- { 47 | Swap(&A[0], &A[i]) //DeleteMax 48 | PercDown(A, 0, i) 49 | } 50 | return A, 1 51 | } 52 | -------------------------------------------------------------------------------- /heapsort/heapsort_test.go: -------------------------------------------------------------------------------- 1 | package heapsort_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Ch3ck/AlGo/heapsort" 8 | ) 9 | 10 | func TestHeapsort(t *testing.T) { 11 | var data = []int{3, 1, 4, 1, 5, 9, 2, 6} //create data 12 | fmt.Println("input: ", data) 13 | var expected = []int{1, 1, 2, 3, 4, 5, 6, 9} 14 | var result, flag = heapsort.Heapsort(data, len(data)) 15 | 16 | if flag != 1 { 17 | fmt.Print("Something went wrong") 18 | return 19 | } 20 | 21 | //check if result is null 22 | if result == nil { 23 | t.Error("returned value is nil") 24 | return 25 | } 26 | 27 | //result is not null, we perform checks 28 | if len(result) != len(expected) { 29 | t.Error("sorted data has different length from input data") 30 | return 31 | } else { //lengths are okay, we compare output values with expected values 32 | for i := range result { 33 | if result[i] != expected[i] { 34 | t.Error("failed at sorting") 35 | } else { 36 | fmt.Println("expect: ", expected) 37 | fmt.Println("output: ", result) 38 | fmt.Println("success") 39 | return 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /insertsort/insertsort.go: -------------------------------------------------------------------------------- 1 | package insertsort 2 | 3 | // Swap is a helper function used to swich the places of 4 | // two items in an array. 5 | func Swap(arraysrt []int, i, j int) { 6 | tmp := arraysrt[j] 7 | arraysrt[j] = arraysrt[i] 8 | arraysrt[i] = tmp 9 | } 10 | 11 | // InsertSort is an implementation of the insert sort 12 | // algorithm. 13 | func InsertSort(array []int) []int { 14 | for i := 1; i < len(array); i++ { 15 | for j := i; j > 0 && array[j] < array[j-1]; j-- { 16 | Swap(array, j, j-1) 17 | } 18 | } 19 | return array 20 | } 21 | -------------------------------------------------------------------------------- /insertsort/insertsort_test.go: -------------------------------------------------------------------------------- 1 | package insertsort 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | /* Test pair for InsertSort() algorithm */ 9 | type testpair struct { 10 | unsortedSlice []int 11 | sortedSlice []int 12 | } 13 | 14 | /* Test instance of testpair the unsorted and sorted slices */ 15 | var tests = []testpair{ 16 | {[]int{3, 2, 1, 5, 6, 3, 7, 8, 9}, []int{1, 2, 3, 3, 5, 6, 7, 8, 9}}, 17 | {[]int{1, 4, 2, 3}, []int{1, 2, 3, 4}}, 18 | {[]int{4, 5, 2, 7, 6, 8, 7}, []int{2, 4, 5, 6, 7, 7, 8}}, 19 | } 20 | 21 | /* Test case to test the InsertSort function */ 22 | func TestInsertSort(t *testing.T) { 23 | for _, pair := range tests { 24 | sorted := InsertSort(pair.unsortedSlice) 25 | 26 | if !reflect.DeepEqual(sorted, pair.sortedSlice) { 27 | t.Error( 28 | "For", pair.unsortedSlice, 29 | "expected", pair.sortedSlice, 30 | "got", sorted, 31 | ) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /knuthMorrisPratt/knuthMorrisPratt.go: -------------------------------------------------------------------------------- 1 | // Package knuthMorrisPratt provides a simple Match function to find occurrences 2 | // of a pattern in a block of text 3 | package knuthMorrisPratt 4 | 5 | // Match uses the Knuth-Morris-Pratt algorithm to find occurrences of `pattern` in `text` 6 | // and returns the list of indexes where the matches are in `text` 7 | func Match(text, pattern string) (result []int) { 8 | n := len(text) 9 | m := len(pattern) 10 | 11 | if n == 0 || m == 0 { 12 | return 13 | } 14 | 15 | pi := prefix(pattern) 16 | q := 0 17 | 18 | for i := 0; i < n; i++ { 19 | for q > 0 && pattern[q] != text[i] { 20 | q = pi[q-1] 21 | } 22 | if pattern[q] == text[i] { 23 | q++ 24 | } 25 | if q == m { 26 | result = append(result, i-m+1) 27 | q = pi[q-1] 28 | } 29 | } 30 | 31 | return 32 | } 33 | 34 | // prefix function, pi, encapsulates knowledege about how a pattern matches againsts 35 | // shifts of itself. 36 | func prefix(pattern string) []int { 37 | m := len(pattern) 38 | if m == 0 { 39 | return []int{} 40 | } 41 | 42 | pi := make([]int, m) 43 | pi[0] = 0 44 | k := 0 45 | for q := 1; q < m; q++ { 46 | for k > 0 && pattern[k] != pattern[q] { 47 | k = pi[k-1] 48 | } 49 | if pattern[k] == pattern[q] { 50 | k++ 51 | } 52 | pi[q] = k 53 | } 54 | 55 | return pi 56 | } 57 | -------------------------------------------------------------------------------- /knuthMorrisPratt/knuthMorrisPratt_test.go: -------------------------------------------------------------------------------- 1 | package knuthMorrisPratt 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestMatchBlankPattern(t *testing.T) { 10 | result := Match("text", "") 11 | assert.Empty(t, result) 12 | } 13 | 14 | func TestMatchBlankText(t *testing.T) { 15 | result := Match("", "pattern") 16 | assert.Empty(t, result) 17 | } 18 | 19 | func TestMatchBlank(t *testing.T) { 20 | result := Match("", "") 21 | assert.Empty(t, result) 22 | } 23 | 24 | func TestMatchSimple(t *testing.T) { 25 | result := Match("abc", "b") 26 | assert.Equal(t, 1, len(result)) 27 | assert.Contains(t, result, 1) 28 | } 29 | 30 | func TestMatchMultiple(t *testing.T) { 31 | result := Match("abcb", "b") 32 | assert.Equal(t, 2, len(result)) 33 | assert.Contains(t, result, 1, 3) 34 | } 35 | 36 | func TestMatchLongPattern(t *testing.T) { 37 | result := Match("abcb", "cb") 38 | assert.Equal(t, 1, len(result)) 39 | assert.Contains(t, result, 2) 40 | } 41 | 42 | func TestMatchLongPatternMultiple(t *testing.T) { 43 | result := Match("acbcacb", "cb") 44 | assert.Equal(t, 2, len(result)) 45 | assert.Contains(t, result, 1, 5) 46 | } 47 | 48 | func TestMatchComplex(t *testing.T) { 49 | result := Match("acbcabcababcbabcaacb", "abcababcbabca") 50 | assert.Equal(t, 1, len(result)) 51 | assert.Contains(t, result, 4) 52 | } 53 | 54 | func TestMatchNoMatch(t *testing.T) { 55 | result := Match("acbcacb", "xyz") 56 | assert.Empty(t, result) 57 | } 58 | 59 | func TestPrefixBlank(t *testing.T) { 60 | result := prefix("") 61 | assert.Empty(t, result) 62 | } 63 | 64 | func TestPrefixSimple(t *testing.T) { 65 | result := prefix("ab") 66 | assert.Equal(t, []int{0, 0}, result) 67 | } 68 | 69 | func TestPrefixLong(t *testing.T) { 70 | result := prefix("abcdefghij") 71 | assert.Equal(t, []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, result) 72 | } 73 | 74 | func TestPrefixSimpleRepeat(t *testing.T) { 75 | result := prefix("aba") 76 | assert.Equal(t, []int{0, 0, 1}, result) 77 | } 78 | func TestPrefixSimpleRepeatSame(t *testing.T) { 79 | result := prefix("aaa") 80 | assert.Equal(t, []int{0, 1, 2}, result) 81 | } 82 | 83 | func TestPrefixComplexRepeat(t *testing.T) { 84 | result := prefix("abcababcbabca") 85 | assert.Equal(t, []int{0, 0, 0, 1, 2, 1, 2, 3, 0, 1, 2, 3, 4}, result) 86 | } 87 | -------------------------------------------------------------------------------- /kruskal/dsu.go: -------------------------------------------------------------------------------- 1 | package kruskal 2 | 3 | // Type holding parent pointer and rank for a DSU node 4 | type Node struct { 5 | parent *Node 6 | rank int 7 | } 8 | 9 | // Recursive implementation of find with path compression 10 | func Find(node *Node) *Node { 11 | // If a node is root of it's component then it has it's parent pointer set to nil 12 | if node.parent == nil { 13 | return node 14 | } else { 15 | node.parent = Find(node.parent) 16 | return node.parent 17 | } 18 | } 19 | 20 | // Implementation of union with ranks, returns a node being the root of the new component 21 | func Union(a, b *Node) *Node { 22 | a = Find(a) 23 | b = Find(b) 24 | 25 | if a == b { 26 | return a 27 | } 28 | 29 | // Swap nodes if needed so that b has higher rank 30 | if a.rank < b.rank { 31 | a, b = b, a 32 | } 33 | 34 | b.parent = a 35 | if a.rank == b.rank { 36 | a.rank++ 37 | } 38 | 39 | return a 40 | } 41 | -------------------------------------------------------------------------------- /kruskal/dsu_test.go: -------------------------------------------------------------------------------- 1 | package kruskal 2 | 3 | import "testing" 4 | 5 | // Tests the DSU implementation 6 | func TestDsu(t *testing.T) { 7 | // Creates 5 one-element sets 8 | nodes := make([]Node, 5) 9 | 10 | // Performs find on an one-element set 11 | if Find(&nodes[0]) != &nodes[0] { 12 | t.Error("Find on an newly created element should return itself") 13 | } 14 | 15 | Union(&nodes[0], &nodes[1]) 16 | Union(&nodes[2], &nodes[3]) 17 | 18 | if Find(&nodes[0]) != Find(&nodes[1]) { 19 | t.Error("Nodes after union should have equal representatives") 20 | } 21 | 22 | // Unions nodes 0, 1, 2, 3 into one set 23 | Union(&nodes[0], &nodes[3]) 24 | Union(&nodes[1], &nodes[3]) 25 | 26 | if Find(&nodes[0]) == Find(&nodes[4]) { 27 | t.Error("Nodes in different sets should have different representatives") 28 | } 29 | 30 | if Find(&nodes[0]) != Find(&nodes[2]) { 31 | t.Error("Nodes in the same set should have equal representatives") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /kruskal/kruskal.go: -------------------------------------------------------------------------------- 1 | // Package provides an implementation of the Kruskal's minimum spanning forest algorithm 2 | // together with an implementation of disjoint set data structure 3 | package kruskal 4 | 5 | import "sort" 6 | 7 | // Type for edge data - endpoints u, v and length 8 | type Edge struct { 9 | u, v, length int 10 | } 11 | 12 | // Type required for calling the sort.Sort method 13 | type Edges []Edge 14 | 15 | func (edges Edges) Swap(i, j int) { 16 | edges[i], edges[j] = edges[j], edges[i] 17 | } 18 | 19 | func (edges Edges) Len() int { 20 | return len(edges) 21 | } 22 | 23 | func (edges Edges) Less(i, j int) bool { 24 | return edges[i].length < edges[j].length 25 | } 26 | 27 | // Computes the minimum spanning forest in a graph with vertices numbered from 0 to n-1 28 | // and a given set of edges. 29 | // Returns the subset of edges forming the minimum spanning forest. 30 | func MinimumSpanningForest(n int, edges []Edge) []Edge { 31 | forestEdges := make([]Edge, 0) 32 | 33 | // Disjoint set union that holds the division of the graph into connected components 34 | nodes := make([]Node, n) 35 | 36 | // Sort edges increasingly by length using the Less() function 37 | sort.Sort(Edges(edges)) 38 | 39 | for _, edge := range edges { 40 | uNode := &nodes[edge.u] 41 | vNode := &nodes[edge.v] 42 | 43 | // If an edge connects two different components, add it to the forest 44 | if Find(uNode) != Find(vNode) { 45 | Union(uNode, vNode) 46 | forestEdges = append(forestEdges, edge) 47 | } 48 | } 49 | 50 | return forestEdges 51 | } 52 | -------------------------------------------------------------------------------- /kruskal/kruskal_test.go: -------------------------------------------------------------------------------- 1 | package kruskal 2 | 3 | import "testing" 4 | 5 | // Tests the kruskal's algorithm 6 | func TestKruskal(t *testing.T) { 7 | edges := []Edge{{4, 5, 10}} 8 | 9 | for i := 0; i < 4; i++ { 10 | for j := i + 1; j < 4; j++ { 11 | edges = append(edges, Edge{i, j, j - i}) 12 | } 13 | } 14 | 15 | // For the given test the answer has cost 13 and is unique 16 | forestEdges := MinimumSpanningForest(6, edges) 17 | 18 | if len(forestEdges) != 4 { 19 | t.Error("Returned set of edges has invalid size") 20 | } 21 | 22 | forestEdgesSet := make(map[Edge]bool) 23 | for _, edge := range forestEdges { 24 | forestEdgesSet[edge] = true 25 | } 26 | 27 | answer := []Edge{{4, 5, 10}} 28 | 29 | for i := 0; i < 3; i++ { 30 | answer = append(answer, Edge{i, i + 1, 1}) 31 | } 32 | 33 | // Checking that each edge from the answer appears amongst the edges returned 34 | // by the algorithm 35 | for _, edge := range answer { 36 | if _, ok := forestEdgesSet[edge]; !ok { 37 | t.Error("Returned set of edges is not a minimum spanning forest") 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /linked-list/linked-list.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package list implements a doubly linked list. 6 | // 7 | // To iterate over a list (where l is a *List): 8 | // for e := l.Front(); e != nil; e = e.Next() { 9 | // // do something with e.Value 10 | // } 11 | // 12 | package list 13 | 14 | // Element is an element of a linked list. 15 | type Element struct { 16 | // Next and previous pointers in the doubly-linked list of elements. 17 | // To simplify the implementation, internally a list l is implemented 18 | // as a ring, such that &l.root is both the next element of the last 19 | // list element (l.Back()) and the previous element of the first list 20 | // element (l.Front()). 21 | next, prev *Element 22 | 23 | // The list to which this element belongs. 24 | list *List 25 | 26 | // The value stored with this element. 27 | Value interface{} 28 | } 29 | 30 | // Next returns the next list element or nil. 31 | func (e *Element) Next() *Element { 32 | if p := e.next; e.list != nil && p != &e.list.root { 33 | return p 34 | } 35 | return nil 36 | } 37 | 38 | // Prev returns the previous list element or nil. 39 | func (e *Element) Prev() *Element { 40 | if p := e.prev; e.list != nil && p != &e.list.root { 41 | return p 42 | } 43 | return nil 44 | } 45 | 46 | // List represents a doubly linked list. 47 | // The zero value for List is an empty list ready to use. 48 | type List struct { 49 | root Element // sentinel list element, only &root, root.prev, and root.next are used 50 | len int // current list length excluding (this) sentinel element 51 | } 52 | 53 | // Init initializes or clears list l. 54 | func (l *List) Init() *List { 55 | l.root.next = &l.root 56 | l.root.prev = &l.root 57 | l.len = 0 58 | return l 59 | } 60 | 61 | // New returns an initialized list. 62 | func New() *List { return new(List).Init() } 63 | 64 | // Len returns the number of elements of list l. 65 | // The complexity is O(1). 66 | func (l *List) Len() int { return l.len } 67 | 68 | // Front returns the first element of list l or nil. 69 | func (l *List) Front() *Element { 70 | if l.len == 0 { 71 | return nil 72 | } 73 | return l.root.next 74 | } 75 | 76 | // Back returns the last element of list l or nil. 77 | func (l *List) Back() *Element { 78 | if l.len == 0 { 79 | return nil 80 | } 81 | return l.root.prev 82 | } 83 | 84 | // lazyInit lazily initializes a zero List value. 85 | func (l *List) lazyInit() { 86 | if l.root.next == nil { 87 | l.Init() 88 | } 89 | } 90 | 91 | // insert inserts e after at, increments l.len, and returns e. 92 | func (l *List) insert(e, at *Element) *Element { 93 | n := at.next 94 | at.next = e 95 | e.prev = at 96 | e.next = n 97 | n.prev = e 98 | e.list = l 99 | l.len++ 100 | return e 101 | } 102 | 103 | // insertValue is a convenience wrapper for insert(&Element{Value: v}, at). 104 | func (l *List) insertValue(v interface{}, at *Element) *Element { 105 | return l.insert(&Element{Value: v}, at) 106 | } 107 | 108 | // remove removes e from its list, decrements l.len, and returns e. 109 | func (l *List) remove(e *Element) *Element { 110 | e.prev.next = e.next 111 | e.next.prev = e.prev 112 | e.next = nil // avoid memory leaks 113 | e.prev = nil // avoid memory leaks 114 | e.list = nil 115 | l.len-- 116 | return e 117 | } 118 | 119 | // Remove removes e from l if e is an element of list l. 120 | // It returns the element value e.Value. 121 | func (l *List) Remove(e *Element) interface{} { 122 | if e.list == l { 123 | // if e.list == l, l must have been initialized when e was inserted 124 | // in l or l == nil (e is a zero Element) and l.remove will crash 125 | l.remove(e) 126 | } 127 | return e.Value 128 | } 129 | 130 | // PushFront inserts a new element e with value v at the front of list l and returns e. 131 | func (l *List) PushFront(v interface{}) *Element { 132 | l.lazyInit() 133 | return l.insertValue(v, &l.root) 134 | } 135 | 136 | // PushBack inserts a new element e with value v at the back of list l and returns e. 137 | func (l *List) PushBack(v interface{}) *Element { 138 | l.lazyInit() 139 | return l.insertValue(v, l.root.prev) 140 | } 141 | 142 | // InsertBefore inserts a new element e with value v immediately before mark and returns e. 143 | // If mark is not an element of l, the list is not modified. 144 | func (l *List) InsertBefore(v interface{}, mark *Element) *Element { 145 | if mark.list != l { 146 | return nil 147 | } 148 | // see comment in List.Remove about initialization of l 149 | return l.insertValue(v, mark.prev) 150 | } 151 | 152 | // InsertAfter inserts a new element e with value v immediately after mark and returns e. 153 | // If mark is not an element of l, the list is not modified. 154 | func (l *List) InsertAfter(v interface{}, mark *Element) *Element { 155 | if mark.list != l { 156 | return nil 157 | } 158 | // see comment in List.Remove about initialization of l 159 | return l.insertValue(v, mark) 160 | } 161 | 162 | // MoveToFront moves element e to the front of list l. 163 | // If e is not an element of l, the list is not modified. 164 | func (l *List) MoveToFront(e *Element) { 165 | if e.list != l || l.root.next == e { 166 | return 167 | } 168 | // see comment in List.Remove about initialization of l 169 | l.insert(l.remove(e), &l.root) 170 | } 171 | 172 | // MoveToBack moves element e to the back of list l. 173 | // If e is not an element of l, the list is not modified. 174 | func (l *List) MoveToBack(e *Element) { 175 | if e.list != l || l.root.prev == e { 176 | return 177 | } 178 | // see comment in List.Remove about initialization of l 179 | l.insert(l.remove(e), l.root.prev) 180 | } 181 | 182 | // MoveBefore moves element e to its new position before mark. 183 | // If e or mark is not an element of l, or e == mark, the list is not modified. 184 | func (l *List) MoveBefore(e, mark *Element) { 185 | if e.list != l || e == mark || mark.list != l { 186 | return 187 | } 188 | l.insert(l.remove(e), mark.prev) 189 | } 190 | 191 | // MoveAfter moves element e to its new position after mark. 192 | // If e or mark is not an element of l, or e == mark, the list is not modified. 193 | func (l *List) MoveAfter(e, mark *Element) { 194 | if e.list != l || e == mark || mark.list != l { 195 | return 196 | } 197 | l.insert(l.remove(e), mark) 198 | } 199 | 200 | // PushBackList inserts a copy of an other list at the back of list l. 201 | // The lists l and other may be the same. 202 | func (l *List) PushBackList(other *List) { 203 | l.lazyInit() 204 | for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { 205 | l.insertValue(e.Value, l.root.prev) 206 | } 207 | } 208 | 209 | // PushFrontList inserts a copy of an other list at the front of list l. 210 | // The lists l and other may be the same. 211 | func (l *List) PushFrontList(other *List) { 212 | l.lazyInit() 213 | for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { 214 | l.insertValue(e.Value, &l.root) 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /linked-list/linked-list_test.go: -------------------------------------------------------------------------------- 1 | package list_test 2 | 3 | import ( 4 | "container/list" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | //create three lists globally 10 | var l = list.New() 11 | var a = list.New() 12 | var b = list.New() 13 | 14 | //method to print list head to tail 15 | func printHeadToTail(l *list.List) { 16 | fmt.Printf("list: ") 17 | for e := l.Front(); e != nil; e = e.Next() { 18 | fmt.Printf("%v ", e.Value) 19 | } 20 | fmt.Println() 21 | } 22 | 23 | //method to print list tail to head 24 | func printTailToHead(l *list.List) { 25 | fmt.Printf("list (reversed): ") 26 | for e := l.Back(); e != nil; e = e.Prev() { 27 | fmt.Printf("%v ", e.Value) 28 | } 29 | fmt.Println() 30 | } 31 | 32 | func TestLinkedListMethods(t *testing.T) { 33 | 34 | //fmt.Println(reflect.TypeOf(l)) 35 | 36 | //list l = [3,4,5] 37 | e3 := l.PushBack(3) 38 | l.PushBack(4) 39 | e5 := l.PushBack(5) 40 | 41 | fmt.Println("List l:") 42 | printHeadToTail(l) 43 | 44 | fmt.Println("\nInsertBefore(2, element3):") 45 | //pass 2, and 6 to list using 46 | //InsertBefore and InsertAfter methods 47 | l.InsertBefore(2, e3) //[(2),3,4,5] 48 | printHeadToTail(l) 49 | 50 | fmt.Println("\nInsertAfter(6, element5):") 51 | l.InsertAfter(6, e5) //[(2),3,4,5,(6)] 52 | printHeadToTail(l) 53 | 54 | //list a = [0,1] 55 | a.PushBack(0) 56 | a.PushBack(1) 57 | 58 | fmt.Println("\nList a:") 59 | printHeadToTail(a) 60 | 61 | //list b = [7,8] 62 | b.PushBack(7) 63 | b.PushBack(8) 64 | 65 | fmt.Println("\nList b:") 66 | printHeadToTail(b) 67 | 68 | fmt.Println("\nPushFrontList(a):") 69 | //append list a to the head (front) of the list 70 | //using PushFrontList 71 | l.PushFrontList(a) //([0,1],2,3,4,5) 72 | printHeadToTail(l) 73 | 74 | fmt.Println("\nPushBackList(b):") 75 | //append list b to the tail (back) of the list 76 | //using PushBackList 77 | l.PushBackList(b) //([0,1],2,3,4,5,6,[7,8]) 78 | printHeadToTail(l) 79 | 80 | //print list length (0,1,2,3,4,5,6,7,8) => 9 elements 81 | fmt.Println("\nLinked list length:", l.Len()) 82 | 83 | fmt.Println("\nPrint list in reverse:") 84 | //print out elements (tail to head) 85 | printTailToHead(l) 86 | 87 | eMinus1 := l.PushBack(-1) 88 | e9 := l.PushFront(9) 89 | 90 | fmt.Println("\nPushBack(-1) and PushFront(9):") 91 | printHeadToTail(l) 92 | 93 | l.MoveToFront(eMinus1) 94 | l.MoveToBack(e9) 95 | 96 | fmt.Println("\nMoveToFront(-1) and MoveToBack(9):") 97 | printHeadToTail(l) 98 | 99 | fmt.Println("\nRemove(Front()):") 100 | e := l.Front() //-1 101 | l.Remove(e) 102 | printHeadToTail(l) 103 | 104 | fmt.Println("\nMoveBefore(Front(), Back())") 105 | e = l.Front() //0 106 | f := l.Back() 107 | l.MoveBefore(e, f) 108 | printHeadToTail(l) 109 | 110 | fmt.Println("\nMoveAfter(Front(), Back())") 111 | l.MoveAfter(e, f) 112 | printHeadToTail(l) 113 | } 114 | -------------------------------------------------------------------------------- /ludecomposition/ludecomposition.go: -------------------------------------------------------------------------------- 1 | // Package provides an algorithm for constructing the LU decomposition 2 | // (with pivoting) of a given matrix. 3 | package ludecomposition 4 | 5 | import ( 6 | "errors" 7 | "math" 8 | ) 9 | 10 | // Applies pivoting to the input. If the given matrix is invertible, 11 | // after pivotization there are no zeros on the main diagonal. 12 | // Returns the permutation that was applied on the rows of the matrix. 13 | func pivotize(matrix [][]float64) (perm []int) { 14 | n := len(matrix) 15 | perm = make([]int, n) 16 | 17 | // Initialize perm to identity permutation 18 | for i := range perm { 19 | perm[i] = i 20 | } 21 | 22 | for i := range matrix { 23 | max := matrix[i][i] 24 | pos := i 25 | 26 | // Extract maximum from the values in matrix[i:n-1][i] 27 | for j := i; j < n; j++ { 28 | if matrix[j][i] > max { 29 | max = matrix[j][i] 30 | pos = j 31 | } 32 | } 33 | 34 | // Swap rows bringing the maximum value to the main diagonal 35 | if pos != i { 36 | perm[i], perm[pos] = perm[pos], perm[i] 37 | matrix[i], matrix[pos] = matrix[pos], matrix[i] 38 | } 39 | } 40 | 41 | return perm 42 | } 43 | 44 | // Returns an n x n identity matrix. 45 | func identityMatrix(n int) (matrix [][]float64) { 46 | matrix = make([][]float64, n) 47 | 48 | for i := range matrix { 49 | matrix[i] = make([]float64, n) 50 | 51 | for j := range matrix[i] { 52 | matrix[i][j] = 0.0 53 | } 54 | 55 | matrix[i][i] = 1.0 56 | } 57 | 58 | return 59 | } 60 | 61 | // Implementation of the LU decomposition algorithm. 62 | // Returns L, U and perm, where L and U form the decomposition, 63 | // and perm is the row permutation applied during pivoting. 64 | // The L matrix has only ones on it's main diagonal, which makes the returned solution 65 | // uniquely defined. 66 | // Raises an error if the input matrix is non-invertible. 67 | func FindLuDecomposition(matrix [][]float64) ([][]float64, [][]float64, []int, error) { 68 | var EPSILON float64 = 1e-9 69 | 70 | n := len(matrix) 71 | 72 | l := identityMatrix(n) 73 | u := make([][]float64, n) 74 | 75 | // Initialize u as a deep copy of the input matrix 76 | for i := range u { 77 | u[i] = make([]float64, n) 78 | copy(u[i], matrix[i]) 79 | } 80 | 81 | perm := pivotize(u) 82 | 83 | for i := range u { 84 | // If after pivotization there are values equal to zero on the main diagonal 85 | // it means that the input matrix is singular, and thus there is no solution 86 | if math.Abs(u[i][i]) < EPSILON { 87 | return nil, nil, nil, errors.New("matrix is singular") 88 | } 89 | } 90 | 91 | for i := range u { 92 | for j := i + 1; j < n; j++ { 93 | ratio := u[j][i] / u[i][i] 94 | 95 | // Zero out u[j][i] by subtracting from the j'th row the i'th row 96 | // multiplied by a suitable coefficient 97 | for k := 0; k < n; k++ { 98 | u[j][k] -= ratio * u[i][k] 99 | } 100 | 101 | // Permorm an analogous column-wise operation 102 | // in order to keep the L*U product constant 103 | for k := 0; k < n; k++ { 104 | l[k][i] += ratio * l[k][j] 105 | } 106 | } 107 | } 108 | 109 | return l, u, perm, nil 110 | } 111 | -------------------------------------------------------------------------------- /ludecomposition/ludecomposition_test.go: -------------------------------------------------------------------------------- 1 | package ludecomposition 2 | 3 | import ( 4 | "math" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | // Holds input and output for a testcase 10 | type testdata struct { 11 | matrix [][]float64 12 | l [][]float64 13 | u [][]float64 14 | perm []int 15 | } 16 | 17 | var tests = []testdata{ 18 | {[][]float64{{4.0, 3.0}, {6.0, 3.0}}, 19 | [][]float64{{1.0, 0.0}, {2.0 / 3.0, 1.0}}, 20 | [][]float64{{6.0, 3.0}, {0.0, 1.0}}, 21 | []int{1, 0}}, 22 | {[][]float64{{3.0, 6.0}, {-3.0, -5.0}}, 23 | [][]float64{{1.0, 0.0}, {-1.0, 1.0}}, 24 | [][]float64{{3.0, 6.0}, {0.0, 1.0}}, 25 | []int{0, 1}}, 26 | {[][]float64{{1.0, 2.0, 1.0}, {3.0, 3.0, 1.0}, {0.0, 9.0, 1.0}}, 27 | [][]float64{{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {3.0 / 9.0, 1.0 / 9.0, 1.0}}, 28 | [][]float64{{3.0, 3.0, 1.0}, {0.0, 9.0, 1.0}, {0.0, 0.0, 5.0 / 9.0}}, 29 | []int{1, 2, 0}}, 30 | } 31 | 32 | // Compares two matrices for equality, considering floating point values 33 | // with absolute difference less than 1e-9 as equal. 34 | func areEqual(a, b [][]float64) bool { 35 | var EPSILON float64 = 1e-9 36 | 37 | if len(a) != len(b) { 38 | return false 39 | } 40 | 41 | for i := range a { 42 | if len(a[i]) != len(b[i]) { 43 | return false 44 | } 45 | 46 | for j := range a[i] { 47 | if math.Abs(a[i][j]-b[i][j]) > EPSILON { 48 | return false 49 | } 50 | } 51 | } 52 | 53 | return true 54 | } 55 | 56 | // Tests the algorithm for LU decomposition. Note that, assuming L has only ones on 57 | // its main diagonal, the solution is unique. 58 | func TestLuDecomposition(t *testing.T) { 59 | for _, test := range tests { 60 | l, u, perm, err := FindLuDecomposition(test.matrix) 61 | 62 | if err != nil { 63 | t.Error("Error occurred:", err) 64 | } 65 | 66 | if !areEqual(l, test.l) { 67 | t.Error( 68 | "For input", test.matrix, 69 | "expected L", test.l, 70 | "got", l, 71 | ) 72 | } 73 | 74 | if !areEqual(u, test.u) { 75 | t.Error( 76 | "For input", test.matrix, 77 | "expected U", test.u, 78 | "got", u, 79 | ) 80 | } 81 | 82 | if !reflect.DeepEqual(perm, test.perm) { 83 | t.Error( 84 | "For input", test.matrix, 85 | "expected permutation", test.perm, 86 | "got", perm, 87 | ) 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /mergesort/mergesort.go: -------------------------------------------------------------------------------- 1 | // Package mergesort provides an implementation for merge sort sorting algorithm 2 | package mergesort 3 | 4 | // MergeSort receives a slice and returns a new sorted slice 5 | func MergeSort(array []int) []int { 6 | if len(array) <= 1 { 7 | result := make([]int, len(array)) 8 | copy(result, array) 9 | return result 10 | } 11 | 12 | mid := len(array) / 2 13 | leftArray := MergeSort(array[:mid]) 14 | rightArray := MergeSort(array[mid:]) 15 | 16 | result := make([]int, len(array)) 17 | 18 | arrayIndex := 0 19 | leftIndex := 0 20 | rightIndex := 0 21 | for leftIndex < len(leftArray) && rightIndex < len(rightArray) { 22 | if leftArray[leftIndex] <= rightArray[rightIndex] { 23 | result[arrayIndex] = leftArray[leftIndex] 24 | leftIndex++ 25 | } else { 26 | result[arrayIndex] = rightArray[rightIndex] 27 | rightIndex++ 28 | } 29 | arrayIndex++ 30 | } 31 | 32 | for leftIndex < len(leftArray) { 33 | result[arrayIndex] = leftArray[leftIndex] 34 | leftIndex++ 35 | arrayIndex++ 36 | } 37 | 38 | for rightIndex < len(rightArray) { 39 | result[arrayIndex] = rightArray[rightIndex] 40 | rightIndex++ 41 | arrayIndex++ 42 | } 43 | 44 | return result 45 | } 46 | -------------------------------------------------------------------------------- /mergesort/mergesort_test.go: -------------------------------------------------------------------------------- 1 | package mergesort 2 | 3 | import ( 4 | "math/rand" 5 | "reflect" 6 | "sort" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestMergeSort(t *testing.T) { 12 | empty := []int{} 13 | resultEmpty := MergeSort(empty) 14 | 15 | if !reflect.DeepEqual(empty, resultEmpty) { 16 | t.Error("ERROR!", "Expected:", empty, "Result:", resultEmpty) 17 | return 18 | } 19 | 20 | unitary := []int{1921} 21 | resultUnitary := MergeSort(unitary) 22 | 23 | if !reflect.DeepEqual(unitary, resultUnitary) { 24 | t.Error("ERROR!", "Expected:", unitary, "Result:", resultUnitary) 25 | return 26 | } 27 | 28 | rand.Seed(int64(time.Now().Nanosecond())) 29 | for test := 0; test < 10; test++ { 30 | array := make([]int, 100) 31 | for i := 0; i < 100; i++ { 32 | array[i] = rand.Int() 33 | } 34 | 35 | expected := make([]int, 100) 36 | copy(expected, array) 37 | sort.Ints(expected) 38 | 39 | result := MergeSort(array) 40 | 41 | if !reflect.DeepEqual(result, expected) { 42 | t.Error("ERROR!", "Expected:", expected, "Result:", result) 43 | return 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /qsort/qsort.go: -------------------------------------------------------------------------------- 1 | /*Package qsort -- Quick Sort Algorithm Data structure implementation: */ 2 | /* This Algorithm takes an slice of integers and */ 3 | /* sort using the qsort() algorithm below */ 4 | /* Author: Alangi Derick (@d3r1ck)*/ 5 | package qsort 6 | 7 | import "math/rand" 8 | 9 | /*Qsort (As GoLang standard, the function in a package should */ 10 | /* start with Upper case letter) */ 11 | func Qsort(slice []int) []int { 12 | 13 | /* Check if the slice has just a single cell */ 14 | /* If it does have just a single cell, return */ 15 | /* the slice. */ 16 | if len(slice) < 2 { 17 | return slice 18 | } 19 | 20 | left, right := 0, len(slice)-1 21 | 22 | /* Pick a pivot in the slice */ 23 | pivotIndex := rand.Int() % len(slice) 24 | 25 | /* Move pivot to the right of slice */ 26 | slice[pivotIndex], slice[right] = slice[right], slice[pivotIndex] 27 | 28 | /* Move elements smaller than pivot to the left */ 29 | for i := range slice { 30 | if slice[i] < slice[right] { 31 | slice[i], slice[left] = slice[left], slice[i] 32 | left++ 33 | } 34 | 35 | } 36 | 37 | /* Place the pivot after the last smaller element */ 38 | slice[left], slice[right] = slice[right], slice[left] 39 | 40 | /* Do a recursive call to the Qsort function */ 41 | /* with new values to sort entire slice */ 42 | Qsort(slice[:left]) 43 | Qsort(slice[left+1:]) 44 | 45 | return slice 46 | } 47 | -------------------------------------------------------------------------------- /qsort/qsort_test.go: -------------------------------------------------------------------------------- 1 | /* Testing the Qsort() function in the qsort package */ 2 | /* Author: Alangi Derick (@d3r1ck), Date: 10/10/2016 */ 3 | 4 | package qsort 5 | 6 | import ( 7 | "reflect" 8 | "testing" 9 | ) 10 | 11 | /* Test pair for Qsort() algorithm */ 12 | type testpair struct { 13 | unsortedSlice []int 14 | sortedSlice []int 15 | } 16 | 17 | /* Test instance of testpair the unsorted and sorted slices */ 18 | var tests = []testpair{ 19 | { 20 | unsortedSlice: []int{3, 2, 1, 5, 6, 3, 7, 8, 9}, 21 | sortedSlice: []int{1, 2, 3, 3, 5, 6, 7, 8, 9}, 22 | }, 23 | { 24 | unsortedSlice: []int{1, 4, 2, 3}, 25 | sortedSlice: []int{1, 2, 3, 4}}, 26 | } 27 | 28 | /* Test case to test the Qsort function */ 29 | func TestQsort(t *testing.T) { 30 | for _, pair := range tests { 31 | sorted := Qsort(pair.unsortedSlice) 32 | 33 | if !reflect.DeepEqual(sorted, pair.sortedSlice) { 34 | t.Error( 35 | "For", pair.unsortedSlice, 36 | "expected", pair.sortedSlice, 37 | "got", sorted, 38 | ) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /queuestack/queue.go: -------------------------------------------------------------------------------- 1 | package queuestack 2 | 3 | import "errors" 4 | 5 | // Queue represents a collection data structure with FIFO (First In First Out) semantics). 6 | type Queue interface { 7 | Enqueue(value interface{}) 8 | Dequeue() (interface{}, error) 9 | Peek() (interface{}, error) 10 | Empty() bool 11 | } 12 | 13 | type queue struct { 14 | data []interface{} 15 | size int 16 | } 17 | 18 | func (q *queue) Enqueue(value interface{}) { 19 | q.data = append(q.data, value) 20 | q.size++ 21 | } 22 | 23 | func (q *queue) Dequeue() (interface{}, error) { 24 | if q.size > 0 { 25 | value := q.data[0] 26 | q.size-- 27 | q.data = q.data[1:] 28 | 29 | return value, nil 30 | } 31 | 32 | return nil, errors.New("no such element") 33 | } 34 | 35 | func (q *queue) Peek() (interface{}, error) { 36 | if q.size > 0 { 37 | value := q.data[0] 38 | return value, nil 39 | } 40 | 41 | return nil, errors.New("no such element") 42 | } 43 | 44 | func (q *queue) Empty() bool { 45 | return q.size == 0 46 | } 47 | 48 | // NewQueue returns an empty queue. 49 | func NewQueue() Queue { 50 | return &queue{} 51 | } 52 | -------------------------------------------------------------------------------- /queuestack/queue_test.go: -------------------------------------------------------------------------------- 1 | package queuestack 2 | 3 | import "testing" 4 | 5 | func TestQueueIsInitiallyEmpty(t *testing.T) { 6 | q := NewQueue() 7 | 8 | if !q.Empty() { 9 | t.Error("newly created queue should contain no elements!") 10 | } 11 | } 12 | 13 | func TestQueueIsNonEmptyAfterEnqueue(t *testing.T) { 14 | q := NewQueue() 15 | 16 | q.Enqueue(1) 17 | 18 | if q.Empty() { 19 | t.Error("queue should not be empty after enqueue-ing any elements!") 20 | } 21 | } 22 | 23 | func TestQueueIsEmptyAfterEnqueueAndDequeue(t *testing.T) { 24 | q := NewQueue() 25 | 26 | q.Enqueue(1) 27 | v, err := q.Dequeue() 28 | 29 | if !q.Empty() { 30 | t.Error("queue should be empty after enqueue-ing and dequeue-ing an element!") 31 | } 32 | 33 | if err != nil { 34 | t.Error("there should not have been anything erroneous occurring after enqueueing and dequeueing an element!") 35 | } 36 | 37 | if v != 1 { 38 | t.Error("value dequeued should be the same as what was enqueued got:", v, "want:", 1) 39 | } 40 | } 41 | 42 | func TestDequeueingAnEmptyQueueErrors(t *testing.T) { 43 | q := NewQueue() 44 | 45 | _, err := q.Dequeue() 46 | 47 | if err == nil { 48 | t.Error("queue should have errored when it was dequeued while empty!") 49 | } 50 | } 51 | 52 | func TestPeekingAnEmptyQueueErrors(t *testing.T) { 53 | q := NewQueue() 54 | 55 | _, err := q.Peek() 56 | 57 | if err == nil { 58 | t.Error("queue should have errored when it was dequeued while empty!") 59 | } 60 | } 61 | 62 | func TestPeekReturnsHeadOfQueue(t *testing.T) { 63 | q := NewQueue() 64 | 65 | q.Enqueue(1) 66 | q.Enqueue(2) 67 | 68 | v, err := q.Peek() 69 | 70 | if err != nil { 71 | t.Error("there should have been nothing erroneous that occurred.") 72 | } 73 | 74 | if v != 1 { 75 | t.Error("queue should have returned the first value in line!") 76 | } 77 | } 78 | 79 | func TestQueueIsFIFOCompliant(t *testing.T) { 80 | q := NewQueue() 81 | 82 | values := []interface{}{0, 1, 2, 3} 83 | 84 | for _, v := range values { 85 | q.Enqueue(v) 86 | } 87 | 88 | for _, v := range values { 89 | dequeued, err := q.Dequeue() 90 | 91 | if err != nil { 92 | t.Fatal("encountered unexpected error:", err) 93 | } 94 | 95 | if v != dequeued { 96 | t.Error("queue is not FIFO compliant") 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /queuestack/stack.go: -------------------------------------------------------------------------------- 1 | package queuestack 2 | 3 | import "errors" 4 | 5 | // Stack represents a collection data structure with LIFO (Last In First Out) semantics). 6 | type Stack interface { 7 | Push(value interface{}) 8 | Pop() (interface{}, error) 9 | Peek() (interface{}, error) 10 | Empty() bool 11 | } 12 | 13 | type stack struct { 14 | data []interface{} 15 | size int 16 | } 17 | 18 | func (s *stack) Push(value interface{}) { 19 | s.data = append(s.data, value) 20 | s.size++ 21 | } 22 | 23 | func (s *stack) Pop() (interface{}, error) { 24 | if s.size > 0 { 25 | value := s.data[s.size-1] 26 | s.size-- 27 | s.data = s.data[:s.size] 28 | return value, nil 29 | } 30 | 31 | return nil, errors.New("no such element") 32 | } 33 | 34 | func (s *stack) Peek() (interface{}, error) { 35 | if s.size > 0 { 36 | value := s.data[s.size-1] 37 | return value, nil 38 | } 39 | 40 | return nil, errors.New("no such element") 41 | } 42 | 43 | func (s *stack) Empty() bool { 44 | return s.size == 0 45 | } 46 | 47 | // NewStack returns an empty stack. 48 | func NewStack() Stack { 49 | return &stack{} 50 | } 51 | -------------------------------------------------------------------------------- /queuestack/stack_test.go: -------------------------------------------------------------------------------- 1 | package queuestack 2 | 3 | import "testing" 4 | 5 | func TestStackIsInitiallyEmpty(t *testing.T) { 6 | s := NewStack() 7 | 8 | if !s.Empty() { 9 | t.Error("newly created stack should contain no elements!") 10 | } 11 | } 12 | 13 | func TestStackIsNonEmptyAfterPush(t *testing.T) { 14 | s := NewStack() 15 | 16 | s.Push(1) 17 | 18 | if s.Empty() { 19 | t.Error("stack should not be empty after pushing any elements!") 20 | } 21 | } 22 | 23 | func TestStackIsEmptyAfterPushAndPop(t *testing.T) { 24 | s := NewStack() 25 | 26 | s.Push(1) 27 | v, err := s.Pop() 28 | 29 | if !s.Empty() { 30 | t.Error("stack should be empty after pushing and popping an element!") 31 | } 32 | 33 | if err != nil { 34 | t.Error("there should not have been anything erroneous occurring after pushing and popping an element:", err) 35 | } 36 | 37 | if v != 1 { 38 | t.Error("value popped should be the same as what was pushed! got:", v, "want:", 1) 39 | } 40 | } 41 | 42 | func TestPoppingAnEmptyStackErrors(t *testing.T) { 43 | s := NewStack() 44 | 45 | _, err := s.Pop() 46 | 47 | if err == nil { 48 | t.Error("stack should have errored when it was popped while empty!") 49 | } 50 | } 51 | 52 | func TestPeekingAnEmptyStackErrors(t *testing.T) { 53 | s := NewStack() 54 | 55 | _, err := s.Peek() 56 | 57 | if err == nil { 58 | t.Error("stack should have errored when it was peeked while empty!") 59 | } 60 | } 61 | 62 | func TestPeekReturnsTopOfStack(t *testing.T) { 63 | s := NewStack() 64 | 65 | s.Push(1) 66 | s.Push(2) 67 | 68 | v, err := s.Peek() 69 | 70 | if err != nil { 71 | t.Error("there should have been nothing erroneous that occurred:", err) 72 | } 73 | 74 | if v != 2 { 75 | t.Error("stack should have returned the top value on the stack! got:", v, "want:", 2) 76 | } 77 | } 78 | 79 | func TestStackIsLIFOCompliant(t *testing.T) { 80 | s := NewStack() 81 | 82 | values := []interface{}{0, 1, 2, 3} 83 | 84 | for _, v := range values { 85 | s.Push(v) 86 | } 87 | 88 | offset := len(values) - 1 89 | for !s.Empty() { 90 | val, err := s.Pop() 91 | 92 | if err != nil { 93 | t.Fatal("encountered unexpected error:", err) 94 | } 95 | 96 | if val != values[offset] { 97 | t.Error("stack is not LIFO compliant") 98 | } 99 | 100 | offset-- 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /rabinkarp/rabinkarp.go: -------------------------------------------------------------------------------- 1 | package rabinkarp 2 | 3 | const base = 2048 4 | 5 | // Search searches given patterns in txt and returns the matched ones. Returns 6 | // empty string slice if there is no match. 7 | func Search(txt string, patterns []string) []string { 8 | in := Indices(txt, patterns) 9 | matches := make([]string, len(in)) 10 | i := 0 11 | for j, p := range patterns { 12 | if _, ok := in[j]; ok { 13 | matches[i] = p 14 | i++ 15 | } 16 | } 17 | 18 | return matches 19 | } 20 | 21 | // Indices returns the Indices of the first occurrence of each pattern in txt. 22 | func Indices(txt string, patterns []string) map[int]int { 23 | n, m := len(txt), MinLen(patterns) 24 | matches := make(map[int]int) 25 | 26 | if n < m || len(patterns) == 0 { 27 | return matches 28 | } 29 | 30 | var mult uint32 = 1 // mult = base^(m-1) 31 | for i := 0; i < m-1; i++ { 32 | mult = (mult * base) 33 | } 34 | 35 | hp := HashPatterns(patterns, m) 36 | h := Hash(txt[:m]) 37 | for i := 0; i < n-m+1 && len(hp) > 0; i++ { 38 | if i > 0 { 39 | h = h - mult*uint32(txt[i-1]) 40 | h = h*base + uint32(txt[i+m-1]) 41 | } 42 | 43 | if mps, ok := hp[h]; ok { 44 | for _, pi := range mps { 45 | pat := patterns[pi] 46 | e := i + len(pat) 47 | if _, ok := matches[pi]; !ok && e <= n && pat == txt[i:e] { 48 | matches[pi] = i 49 | } 50 | } 51 | } 52 | } 53 | return matches 54 | } 55 | 56 | // Hash converts a string into a uint32 hash. 57 | func Hash(s string) uint32 { 58 | var h uint32 59 | for i := 0; i < len(s); i++ { 60 | h = (h*base + uint32(s[i])) 61 | } 62 | return h 63 | } 64 | 65 | // HashPatterns takes a slice of patterns and creates a map of 66 | // patterns to their hashed value. 67 | func HashPatterns(patterns []string, l int) map[uint32][]int { 68 | m := make(map[uint32][]int) 69 | for i, t := range patterns { 70 | h := Hash(t[:l]) 71 | if _, ok := m[h]; ok { 72 | m[h] = append(m[h], i) 73 | } else { 74 | m[h] = []int{i} 75 | } 76 | } 77 | 78 | return m 79 | } 80 | 81 | // MinLen returns the patterns of the smallest length. 82 | func MinLen(patterns []string) int { 83 | if len(patterns) == 0 { 84 | return 0 85 | } 86 | 87 | m := len(patterns[0]) 88 | for i := range patterns { 89 | if m > len(patterns[i]) { 90 | m = len(patterns[i]) 91 | } 92 | } 93 | 94 | return m 95 | } 96 | -------------------------------------------------------------------------------- /rabinkarp/rabinkarp_test.go: -------------------------------------------------------------------------------- 1 | package rabinkarp 2 | 3 | import ( 4 | "reflect" 5 | "sort" 6 | "testing" 7 | ) 8 | 9 | // Struct for test data 10 | var SearchTests = []struct { 11 | txt string 12 | patterns []string 13 | expected []string 14 | }{ 15 | {"walter h white", []string{"white", "pinkman", "walter"}, []string{"walter", "white"}}, 16 | {"damon salvatore", []string{"damon", "stephen", "salvatore"}, []string{"damon", "salvatore"}}, 17 | } 18 | 19 | // run testcase 20 | func TestSearch(t *testing.T) { 21 | for _, ct := range SearchTests { 22 | found := Search(ct.txt, ct.patterns) 23 | if !eq(found, ct.expected) { 24 | t.Error("Broken test .....", 25 | ct.txt, ct.patterns, found, ct.expected) 26 | } 27 | } 28 | } 29 | 30 | // sort string for comparison 31 | func eq(f, s []string) bool { 32 | fx := make([]string, len(f)) 33 | sx := make([]string, len(s)) 34 | copy(fx, f) 35 | copy(sx, s) 36 | 37 | sort.Strings(fx) 38 | sort.Strings(sx) 39 | return reflect.DeepEqual(fx, sx) 40 | } 41 | -------------------------------------------------------------------------------- /rbtree/rbtree.go: -------------------------------------------------------------------------------- 1 | package rbtree 2 | 3 | import "fmt" 4 | 5 | // color of node 6 | const ( 7 | RED = 0 8 | BLACK = 1 9 | ) 10 | 11 | type keytype interface { 12 | LessThan(interface{}) bool 13 | } 14 | 15 | type valuetype interface{} 16 | 17 | type node struct { 18 | left, right, parent *node 19 | color int 20 | Key keytype 21 | Value valuetype 22 | } 23 | 24 | // Tree is a struct of red-black tree 25 | type Tree struct { 26 | root *node 27 | size int 28 | } 29 | 30 | // NewTree returns a new rbtree 31 | func NewTree() *Tree { 32 | return &Tree{} 33 | } 34 | 35 | // Find finds the node and return its value 36 | func (t *Tree) Find(key keytype) interface{} { 37 | n := t.findnode(key) 38 | if n != nil { 39 | return n.Value 40 | } 41 | return nil 42 | } 43 | 44 | // FindIt finds the node and return it as a iterator 45 | func (t *Tree) FindIt(key keytype) *node { 46 | return t.findnode(key) 47 | } 48 | 49 | // Empty checks whether the rbtree is empty 50 | func (t *Tree) Empty() bool { 51 | if t.root == nil { 52 | return true 53 | } 54 | return false 55 | } 56 | 57 | // Iterator creates the rbtree's iterator that points to the minmum node 58 | func (t *Tree) Iterator() *node { 59 | return minimum(t.root) 60 | } 61 | 62 | // Size returns the size of the rbtree 63 | func (t *Tree) Size() int { 64 | return t.size 65 | } 66 | 67 | // Clear destroys the rbtree 68 | func (t *Tree) Clear() { 69 | t.root = nil 70 | t.size = 0 71 | } 72 | 73 | // Insert inserts the key-value pair into the rbtree 74 | func (t *Tree) Insert(key keytype, value valuetype) { 75 | x := t.root 76 | var y *node 77 | 78 | for x != nil { 79 | y = x 80 | if key.LessThan(x.Key) { 81 | x = x.left 82 | } else { 83 | x = x.right 84 | } 85 | } 86 | 87 | z := &node{parent: y, color: RED, Key: key, Value: value} 88 | t.size++ 89 | 90 | if y == nil { 91 | z.color = BLACK 92 | t.root = z 93 | return 94 | } else if z.Key.LessThan(y.Key) { 95 | y.left = z 96 | } else { 97 | y.right = z 98 | } 99 | t.rbInsertFixup(z) 100 | 101 | } 102 | 103 | // Delete deletes the node by key 104 | func (t *Tree) Delete(key keytype) { 105 | z := t.findnode(key) 106 | if z == nil { 107 | return 108 | } 109 | 110 | var x, y, parent *node 111 | y = z 112 | yOriginalColor := y.color 113 | parent = z.parent 114 | if z.left == nil { 115 | x = z.right 116 | t.transplant(z, z.right) 117 | } else if z.right == nil { 118 | x = z.left 119 | t.transplant(z, z.left) 120 | } else { 121 | y = minimum(z.right) 122 | yOriginalColor = y.color 123 | x = y.right 124 | 125 | if y.parent == z { 126 | if x == nil { 127 | parent = y 128 | } else { 129 | x.parent = y 130 | } 131 | } else { 132 | t.transplant(y, y.right) 133 | y.right = z.right 134 | y.right.parent = y 135 | } 136 | t.transplant(z, y) 137 | y.left = z.left 138 | y.left.parent = y 139 | y.color = z.color 140 | } 141 | 142 | if yOriginalColor == BLACK { 143 | t.rbDeleteFixup(x, parent) 144 | } 145 | t.size-- 146 | } 147 | 148 | func (t *Tree) rbInsertFixup(z *node) { 149 | var y *node 150 | for z.parent != nil && z.parent.color == RED { 151 | if z.parent == z.parent.parent.left { 152 | y = z.parent.parent.right 153 | if y != nil && y.color == RED { 154 | z.parent.color = BLACK 155 | y.color = BLACK 156 | z.parent.parent.color = RED 157 | z = z.parent.parent 158 | } else { 159 | if z == z.parent.right { 160 | z = z.parent 161 | t.leftRotate(z) 162 | } 163 | z.parent.color = BLACK 164 | z.parent.parent.color = RED 165 | t.rightRotate(z.parent.parent) 166 | } 167 | } else { 168 | y = z.parent.parent.left 169 | if y != nil && y.color == RED { 170 | z.parent.color = BLACK 171 | y.color = BLACK 172 | z.parent.parent.color = RED 173 | z = z.parent.parent 174 | } else { 175 | if z == z.parent.left { 176 | z = z.parent 177 | t.rightRotate(z) 178 | } 179 | z.parent.color = BLACK 180 | z.parent.parent.color = RED 181 | t.leftRotate(z.parent.parent) 182 | } 183 | } 184 | } 185 | t.root.color = BLACK 186 | } 187 | 188 | func (t *Tree) rbDeleteFixup(x, parent *node) { 189 | var w *node 190 | 191 | for x != t.root && getColor(x) == BLACK { 192 | if x != nil { 193 | parent = x.parent 194 | } 195 | if x == parent.left { 196 | w = parent.right 197 | if w.color == RED { 198 | w.color = BLACK 199 | parent.color = RED 200 | t.leftRotate(parent) 201 | w = parent.right 202 | } 203 | if getColor(w.left) == BLACK && getColor(w.right) == BLACK { 204 | w.color = RED 205 | x = parent 206 | } else { 207 | if getColor(w.right) == BLACK { 208 | if w.left != nil { 209 | w.left.color = BLACK 210 | } 211 | w.color = RED 212 | t.rightRotate(w) 213 | w = parent.right 214 | } 215 | w.color = parent.color 216 | parent.color = BLACK 217 | if w.right != nil { 218 | w.right.color = BLACK 219 | } 220 | t.leftRotate(parent) 221 | x = t.root 222 | } 223 | } else { 224 | w = parent.left 225 | if w.color == RED { 226 | w.color = BLACK 227 | parent.color = RED 228 | t.rightRotate(parent) 229 | w = parent.left 230 | } 231 | if getColor(w.left) == BLACK && getColor(w.right) == BLACK { 232 | w.color = RED 233 | x = parent 234 | } else { 235 | if getColor(w.left) == BLACK { 236 | if w.right != nil { 237 | w.right.color = BLACK 238 | } 239 | w.color = RED 240 | t.leftRotate(w) 241 | w = parent.left 242 | } 243 | w.color = parent.color 244 | parent.color = BLACK 245 | if w.left != nil { 246 | w.left.color = BLACK 247 | } 248 | t.rightRotate(parent) 249 | x = t.root 250 | } 251 | } 252 | } 253 | if x != nil { 254 | x.color = BLACK 255 | } 256 | } 257 | 258 | func (t *Tree) leftRotate(x *node) { 259 | y := x.right 260 | x.right = y.left 261 | if y.left != nil { 262 | y.left.parent = x 263 | } 264 | y.parent = x.parent 265 | if x.parent == nil { 266 | t.root = y 267 | } else if x == x.parent.left { 268 | x.parent.left = y 269 | } else { 270 | x.parent.right = y 271 | } 272 | y.left = x 273 | x.parent = y 274 | } 275 | 276 | func (t *Tree) rightRotate(x *node) { 277 | y := x.left 278 | x.left = y.right 279 | if y.right != nil { 280 | y.right.parent = x 281 | } 282 | y.parent = x.parent 283 | if x.parent == nil { 284 | t.root = y 285 | } else if x == x.parent.left { 286 | x.parent.left = y 287 | } else { 288 | x.parent.right = y 289 | } 290 | y.right = x 291 | x.parent = y 292 | } 293 | 294 | // Preorder prints the tree in pre order 295 | func (t *Tree) Preorder() { 296 | fmt.Println("preorder begin!") 297 | if t.root != nil { 298 | t.root.preorder() 299 | } 300 | fmt.Println("preorder end!") 301 | } 302 | 303 | // findnode finds the node by key and return it,if not exists return nil 304 | func (t *Tree) findnode(key keytype) *node { 305 | x := t.root 306 | for x != nil { 307 | if key.LessThan(x.Key) { 308 | x = x.left 309 | } else { 310 | if key == x.Key { 311 | return x 312 | } 313 | x = x.right 314 | } 315 | } 316 | return nil 317 | } 318 | 319 | // transplant transplants the subtree u and v 320 | func (t *Tree) transplant(u, v *node) { 321 | if u.parent == nil { 322 | t.root = v 323 | } else if u == u.parent.left { 324 | u.parent.left = v 325 | } else { 326 | u.parent.right = v 327 | } 328 | if v == nil { 329 | return 330 | } 331 | v.parent = u.parent 332 | } 333 | 334 | // Next returns the node's successor as an iterator 335 | func (n *node) Next() *node { 336 | return successor(n) 337 | } 338 | 339 | func (n *node) preorder() { 340 | fmt.Printf("(%v %v)", n.Key, n.Value) 341 | if n.parent == nil { 342 | fmt.Printf("nil") 343 | } else { 344 | fmt.Printf("whose parent is %v", n.parent.Key) 345 | } 346 | if n.color == RED { 347 | fmt.Println(" and color RED") 348 | } else { 349 | fmt.Println(" and color BLACK") 350 | } 351 | if n.left != nil { 352 | fmt.Printf("%v's left child is ", n.Key) 353 | n.left.preorder() 354 | } 355 | if n.right != nil { 356 | fmt.Printf("%v's right child is ", n.Key) 357 | n.right.preorder() 358 | } 359 | } 360 | 361 | // successor returns the successor of the node 362 | func successor(x *node) *node { 363 | if x.right != nil { 364 | return minimum(x.right) 365 | } 366 | y := x.parent 367 | for y != nil && x == y.right { 368 | x = y 369 | y = x.parent 370 | } 371 | return y 372 | } 373 | 374 | // getColor gets color of the node 375 | func getColor(n *node) int { 376 | if n == nil { 377 | return BLACK 378 | } 379 | return n.color 380 | } 381 | 382 | // minimum finds the minimum node of subtree n. 383 | func minimum(n *node) *node { 384 | for n.left != nil { 385 | n = n.left 386 | } 387 | return n 388 | } 389 | 390 | // maximum finds the maximum node of subtree n. 391 | func maximum(n *node) *node { 392 | for n.right != nil { 393 | n = n.right 394 | } 395 | return n 396 | } 397 | -------------------------------------------------------------------------------- /rbtree/rbtree_test.go: -------------------------------------------------------------------------------- 1 | package rbtree 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | type key int 8 | 9 | func (n key) LessThan(b interface{}) bool { 10 | value, _ := b.(key) 11 | return n < value 12 | } 13 | 14 | func TestPreorder(t *testing.T) { 15 | tree := NewTree() 16 | 17 | tree.Insert(key(1), "123") 18 | tree.Insert(key(3), "234") 19 | tree.Insert(key(4), "dfa3") 20 | tree.Insert(key(6), "sd4") 21 | tree.Insert(key(5), "jcd4") 22 | tree.Insert(key(2), "bcd4") 23 | if tree.Size() != 6 { 24 | t.Error("Error size") 25 | } 26 | tree.Preorder() 27 | } 28 | 29 | func TestFind(t *testing.T) { 30 | 31 | tree := NewTree() 32 | 33 | tree.Insert(key(1), "123") 34 | tree.Insert(key(3), "234") 35 | tree.Insert(key(4), "dfa3") 36 | tree.Insert(key(6), "sd4") 37 | tree.Insert(key(5), "jcd4") 38 | tree.Insert(key(2), "bcd4") 39 | 40 | n := tree.FindIt(key(4)) 41 | if n.Value != "dfa3" { 42 | t.Error("Error value") 43 | } 44 | n.Value = "bdsf" 45 | if n.Value != "bdsf" { 46 | t.Error("Error value modify") 47 | } 48 | value := tree.Find(key(5)).(string) 49 | if value != "jcd4" { 50 | t.Error("Error value after modifyed other node") 51 | } 52 | } 53 | func TestIterator(t *testing.T) { 54 | tree := NewTree() 55 | 56 | tree.Insert(key(1), "123") 57 | tree.Insert(key(3), "234") 58 | tree.Insert(key(4), "dfa3") 59 | tree.Insert(key(6), "sd4") 60 | tree.Insert(key(5), "jcd4") 61 | tree.Insert(key(2), "bcd4") 62 | 63 | it := tree.Iterator() 64 | 65 | for it != nil { 66 | it = it.Next() 67 | } 68 | 69 | } 70 | 71 | func TestDelete(t *testing.T) { 72 | tree := NewTree() 73 | 74 | tree.Insert(key(1), "123") 75 | tree.Insert(key(3), "234") 76 | tree.Insert(key(4), "dfa3") 77 | tree.Insert(key(6), "sd4") 78 | tree.Insert(key(5), "jcd4") 79 | tree.Insert(key(2), "bcd4") 80 | for i := 1; i <= 6; i++ { 81 | tree.Delete(key(i)) 82 | if tree.Size() != 6-i { 83 | t.Error("Delete Error") 84 | } 85 | } 86 | tree.Insert(key(1), "bcd4") 87 | tree.Clear() 88 | tree.Preorder() 89 | if tree.Find(key(1)) != nil { 90 | t.Error("Can't clear") 91 | } 92 | } 93 | 94 | func TestDelete2(t *testing.T) { 95 | tree := NewTree() 96 | tree.Insert(key(4), "1qa") 97 | tree.Insert(key(2), "2ws") 98 | tree.Insert(key(3), "3ed") 99 | tree.Insert(key(1), "4rf") 100 | tree.Insert(key(8), "5tg") 101 | tree.Insert(key(5), "6yh") 102 | tree.Insert(key(7), "7uj") 103 | tree.Insert(key(9), "8ik") 104 | tree.Delete(key(1)) 105 | tree.Delete(key(2)) 106 | } 107 | -------------------------------------------------------------------------------- /stack/stack.go: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | // Element is an element of a stack 4 | type Element struct { 5 | // The value stored with this element 6 | Value interface{} 7 | } 8 | 9 | // Stack represents a stack 10 | type Stack struct { 11 | items []Element // items of your stack 12 | length int // current stack length 13 | } 14 | 15 | // Init initializes or clears the stack s 16 | func (s *Stack) Init() *Stack { 17 | s.items = nil 18 | s.length = 0 19 | return s 20 | } 21 | 22 | // New returns an initialized stack 23 | func New() *Stack { 24 | return new(Stack).Init() 25 | } 26 | 27 | // Len (Length) returns the number of elements of the stack s. 28 | // The complexity is O(1) 29 | func (s *Stack) Len() int { 30 | return s.length 31 | } 32 | 33 | // IsEmpty returns true if the stack s is empty 34 | func (s *Stack) IsEmpty() bool { 35 | return s.length == 0 36 | } 37 | 38 | // Push inserts an item into the stack 39 | func (s *Stack) Push(v interface{}) { 40 | s.items = append(s.items[:s.length], Element{Value: v}) 41 | s.length++ 42 | } 43 | 44 | // Pop removes an item from the stack 45 | func (s *Stack) Pop() interface{} { 46 | if s.length == 0 { 47 | return nil 48 | } 49 | ToRemove := s.items[s.length-1] 50 | s.items = s.items[:(s.length - 1)] 51 | s.length-- 52 | return ToRemove.Value 53 | } 54 | 55 | // Peek shows you the last element of the stack 56 | func (s *Stack) Peek() interface{} { 57 | if s.length == 0 { 58 | return nil 59 | } 60 | return s.items[s.length-1].Value 61 | } 62 | -------------------------------------------------------------------------------- /stack/stack_test.go: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestStack(t *testing.T) { 8 | var data = []int{0, 1, 2, 3, 4} 9 | s := new(Stack) 10 | 11 | for i := 0; i < len(data); i++ { 12 | s.Push(data[i]) 13 | } 14 | 15 | N := s.Len() 16 | if N != 5 { 17 | t.Error("stack length should be 5") 18 | } 19 | 20 | for i := 0; i < N; i++ { 21 | s.Pop() 22 | } 23 | 24 | if !s.IsEmpty() { 25 | t.Error("stack should be empty") 26 | } 27 | 28 | for i := 0; i < len(data)-1; i++ { 29 | s.Push(data[i]) 30 | } 31 | 32 | if s.IsEmpty() { 33 | t.Error("stack should not be empty") 34 | } 35 | 36 | if s.Peek() != 3 { 37 | t.Error("peek should return 3") 38 | } 39 | 40 | s.Init() 41 | 42 | if !s.IsEmpty() { 43 | t.Error("stack should be empty") 44 | } 45 | } 46 | --------------------------------------------------------------------------------