{"id":15037777,"url":"https://github.com/alexdrone/datastructures","last_synced_at":"2025-04-09T23:32:53.393Z","repository":{"id":147419739,"uuid":"48744363","full_name":"alexdrone/DataStructures","owner":"alexdrone","description":"A collection of Data Structures implemented in Swift.","archived":false,"fork":false,"pushed_at":"2018-03-28T18:32:27.000Z","size":353,"stargazers_count":49,"open_issues_count":0,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-24T01:22:53.230Z","etag":null,"topics":["avl-tree","bimap","binary-heap","bloom-filter","datastructures","graph","linkedlist","multimap","priority-queue","queue","red-black-trees","stack","swift","swift-3","trie"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexdrone.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-29T11:27:21.000Z","updated_at":"2023-11-21T03:57:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"5709eb01-c538-4130-a3e2-7917cd96295b","html_url":"https://github.com/alexdrone/DataStructures","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdrone%2FDataStructures","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdrone%2FDataStructures/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdrone%2FDataStructures/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdrone%2FDataStructures/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexdrone","download_url":"https://codeload.github.com/alexdrone/DataStructures/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248129966,"owners_count":21052670,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avl-tree","bimap","binary-heap","bloom-filter","datastructures","graph","linkedlist","multimap","priority-queue","queue","red-black-trees","stack","swift","swift-3","trie"],"created_at":"2024-09-24T20:35:39.440Z","updated_at":"2025-04-09T23:32:53.363Z","avatar_url":"https://github.com/alexdrone.png","language":"Swift","readme":"# DataStructures\n\n[![Swift](https://img.shields.io/badge/swift-3-orange.svg?style=flat)](#)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![Build](https://img.shields.io/badge/build-passing-green.svg?style=flat)](#)\n[![Build](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://opensource.org/licenses/MIT)\n\nA collection of data structures implemented in Swift.\n\n\nThe available data structures are:\n\n- LinkedList\n- SortedLinkedList\n- Stack\n- Queue\n- Graph \n- BinaryHeap\n- PriorityQueue*\n- BloomFilter*\n- Trie*\n- Multimap*\n- Bimap*\n- Bag\n- BinarySearchTree\n- RedBlackTree*\n- AVLTree\n\n## Installation\n\n### Carthage\n\nTo install Carthage, run (using Homebrew):\n\n```bash\n$ brew update\n$ brew install carthage\n```\n\nThen add the following line to your `Cartfile`:\n\n```\ngithub \"alexdrone/DataStructures\" \"master\"    \n```\n\n## Usage\n\nAll collection types are implemented as structures with the exception of the LinkedList data structure. This means they are copied when they are assigned to a new constant or variable, or when they are passed to a function or method. \n\nAbout copying structs:  \n\n\u003e The behavior you see in your code will always be as if a copy took place. However, Swift only performs an actual copy behind the scenes when it is absolutely necessary to do so. Swift manages all value copying to ensure optimal performance, and you should not avoid assignment to try to preempt this optimization.\n\n## Data Structures\n\n#### LinkedList\n\nAll of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.\n\nNote that this implementation is not synchronized. If multiple threads access a linked list concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.\n\n```swift\nlet linkedList = LinkedList\u003cInt\u003e()\nlinkedList.append(1)\nlinkedList.append(2)\n\nprint(linkedList) //[1,2]\n\nlet sortedLinkedList = SortedLinkedList\u003cInt\u003e()\nlinkedList.append(3)\nlinkedList.append(1)\nlinkedList.append(2)\n\nprint(sortedLinkedList) //[1,2,3]\n\n```\n\n#### Graph\n\nA graph can be constructed from a array literal, or a dependency list.\nOperations like *BFS* and *DFS* visit, *shortestPath* and *topologicalSort* are available to the user.\n\nNote that this implementation is not synchronized, it must be synchronized externally.\n\n```swift\n//Graph (graphs can be directed/undirected and weighted/not weighted)\nvar graph = Graph\u003cInt\u003e(arrayLiteral: 1,7,4,3,5,2,6)\n\ngraph.addEdge(graph[1], to: graph[2])\ngraph.addEdge(graph[1], to: graph[3])\ngraph.addEdge(graph[1], to: graph[5])\ngraph.addEdge(graph[2], to: graph[4])\ngraph.addEdge(graph[4], to: graph[5])\ngraph.addEdge(graph[5], to: graph[6])\n        \n\n//bfs visit expected [1, 2, 3, 5, 4, 6]\nlet bfs = graph.traverseBreadthFirst().map() { return $0.value }\n\n//shortest path\n\nvar g = Graph\u003cInt\u003e(arrayLiteral: 1,7,4,3,5,2,6)\ng.directed = true\ng.weighted = true\n\ng.addEdge()g[1], to:g[2], weight: 2)\ng.addEdge(g[1], to:g[3], weight: 3)\ng.addEdge(g[1], to:g[5], weight: 6)\ng.addEdge(g[2], to:g[4], weight: 1)\ng.addEdge(g[4], to:g[5], weight: 1)\ng.addEdge(g[5], to:g[6], weight: 10)\n\n//..or you can use the shorthand subscript to create an edge\n graph[1,2] = 2\n graph[1,3] = 3\n graph[1,5] = 6\n graph[2,4] = 1\n graph[4,5] = 1\n graph[5,6] = 10\n\n//shortest path from 1 to 5, expected [1, 2, 4, 5] with cost 4\nlet p = g.shortestPath(g[1], to: g[5])\n(p?.vertices.map(){ return $0.value} //[1,2,4,5]\n\n///topological sort and cycle check\nlet noCycle: Dictionary\u003cString, [String]\u003e = [ \"A\": [],  \"B\": [],  \"C\": [\"D\"], \"D\": [\"A\"], \"E\": [\"C\", \"B\"],  \"F\": [\"E\"] ]\n\nvar g = Graph\u003cString\u003e(directed: true, weighted: false)\ng.populateFromDependencyList(noCycle)\n\ng.isDirectedAcyclic() //true\ng.topologicalSort() // [\"A\", \"B\", \"D\", \"C\", \"E\", \"F\"]\n\n```\n\n#### Stack and Queue\n\nStacks and Queues are implemented through Array and LinkedList extension\nNote that this implementation is not synchronized, it must be synchronized externally.\n\n```swift\n\nextension LinkedList : Stack {\n    public func pop() -\u003e T?\n    public func push(element: T)\n    public func peekStack() -\u003e T?\n}\n\nextension Array : Stack {\n    public func pop() -\u003e T?\n    public func push(element: T)\n    public func peekStack() -\u003e T?\n}\n\nextension LinkedList: Queue {\n    public func enqueue(element: Q)    \n    public func dequeue() -\u003e Q?     \n    public func peekQueue() -\u003e Q?\n}\n\nextension Array: Queue {\n    public func enqueue(element: Q)    \n    public func dequeue() -\u003e Q?     \n    public func peekQueue() -\u003e Q?\n}\n\n```\n\n#### PriorityQueue\nAn unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to the sort closure passed as argument in the constructor.\nThe head of this queue is the least element with respect to the specified ordering. If multiple elements are tied for least value, the head is one of those elements -- ties are broken arbitrarily.\n\nNote that this implementation is not synchronized. Multiple threads should not access a PriorityQueue instance concurrently if any of the threads modifies the queue\n\n```swift\nvar pQueue = PriorityQueue\u003cInt\u003e(\u003c)\npQueue.enqueue(3)\npQueue.enqueue(1)\npQueue.enqueue(2)\npQueue.dequeue() // 1\n\n```\n\n#### BloomFilter\n\nA Bloom filter is a space-efficient probabilistic data structure that is used to test whether an element is a member of a set. False positive matches are possible, but false negatives are not, thus a Bloom filter has a 100% recall rate. In other words, a query returns either \"possibly in set\" or \"definitely not in set\".\n\n```swift\nvar bFilter = BloomFilter\u003cString\u003e(expectedCount: 100)\nbFilter.insert(\"a\")\nbFilter.contains(\"a\") // true\n\n```\n\n#### Trie\n\nIs an ordered tree data structure that is used to store a dynamic set or associative array where the keys are strings.\nNote that this implementation is not synchronized, it must be synchronized externally.\n\n```swift\nvar trie = Trie()\ntrie.insert(\"A\")\ntrie.insert(\"AB\")\ntrie.findPrefix(\"A\") // [\"A\", \"AB\"]\n\n```\n#### RedBlackTree\n\nA red–black tree is a kind of self-balancing binary search tree. \nBalance is preserved by painting each node of the tree with one of two colors (typically called 'red' and 'black') in a way that satisfies certain properties, which collectively constrain how unbalanced the tree can become in the worst case.\n\n\nThe balancing of the tree is not perfect but it is good enough to allow it to guarantee searching in O(log n) time, where n is the total number of elements in the tree. The insertion and deletion operations, along with the tree rearrangement and recoloring, are also performed in O(log n) time.\n\nNote that this implementation is not synchronized, it must be synchronized externally.\n\n```swift\nimport DataStructures\n\n var tree = RedBlackTree\u003cInt\u003e(arrayLiteral:[1, 3, 5, 6, 7, 8, 9])\n tree.popFirst()\n\n```\n\n#### Multimap\n\nA generalization of a map or associative array data type in which more than one value may be associated with and returned for a given key.\nNote that this implementation is not synchronized, it must be synchronized externally.\n\n\n```swift\nvar multimap = Multimap\u003cString, Int\u003e()\nmultimap.insertValue(1, forKey: \"a\")\nmultimap.insertValue(5, forKey: \"a\")\nmultimap[\"a\"] // [1, 5]\n\n```\n\n#### Bimap\n\nA generalization of a map or associative array data type in which more than one value may be associated with and returned for a given key.\nNote that this implementation is not synchronized, it must be synchronized externally.\n\n\n```swift\nvar bimap = Bimap\u003cString, Int\u003e()\nbimap[key: \"a\"] = 1\nbimap[value: 3] = \"b\"\nbimap[value: 1] // \"a\"\nbimap[key: \"b\"] // 3\n\n```\n\n#### Bag\n\nSimilar to a set but allows repeated (\"equal\") values (duplicates). This is used in two distinct senses: either equal values are considered identical, and are simply counted, or equal values are considered equivalent, and are stored as distinct items. \n\n```swift\nvar bag = Bag\u003cString\u003e()\nbag.insert(\"a\")\nbag.insert(\"b\")\nbag.insert(\"a\")\nbag.distinctCount // 2\nbag.count(\"a\") // 2\n\n```\n\n## Additions\n\n#### Edit Distance for Arrays\n\nThe edit distance is a way of quantifying how dissimilar two arrays are to one another by counting the minimum number of operations required to transform one array into the other\n\n```swift\npublic enum EditDistanceOperation {\n    \n    case Insertion(source: Int, target: Int)\n    case Removal(source: Int)\n    case Substitution(source: Int, target: Int)\n    case AllChanged\n\n    public static func compute\u003cT:Equatable\u003e(from: [T], to: [T]) -\u003e [EditDistanceOperation]\n\n```\n\n#### Bitmask Operations\n\n```swift\npublic struct BitMask {\n    \n    ///Check the bit at the given index\n    public static func check(n: Int, index: Int) -\u003e Bool\n    \n    ///Set the bit to 1 at the index passed as argument\n    public static func set(n: Int, index: Int) -\u003e Int\n    \n    ///Clear the bit passed as argument\n    public static func clear(n: Int, index: Int) -\u003e Int\n}\n\n```\n\n## Credits\n\\* The PriorityQueue,Multimap,Bimap and BloomFilter data structures are forked from the excellent [Buckets](https://github.com/mauriciosantos/Buckets-Swift/) github project. I higly suggest to check it out!\nThe RedBlackTree datastructure is adapted from [SwiftDataStructures](https://github.com/oisdk/SwiftDataStructures) \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexdrone%2Fdatastructures","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexdrone%2Fdatastructures","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexdrone%2Fdatastructures/lists"}