{"id":18474149,"url":"https://github.com/prprprus/gds","last_synced_at":"2025-05-13T00:54:04.282Z","repository":{"id":49869374,"uuid":"193045889","full_name":"prprprus/gds","owner":"prprprus","description":"Implement Data Structures With Go.","archived":false,"fork":false,"pushed_at":"2021-06-09T13:15:33.000Z","size":201,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-13T00:53:58.717Z","etag":null,"topics":["datastructures","go","golang","implement","implementation"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prprprus.png","metadata":{"files":{"readme":"README-zh.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-21T06:45:55.000Z","updated_at":"2024-05-17T02:54:47.000Z","dependencies_parsed_at":"2022-09-07T17:20:46.249Z","dependency_job_id":null,"html_url":"https://github.com/prprprus/gds","commit_stats":null,"previous_names":["prprprus/ds"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prprprus%2Fgds","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prprprus%2Fgds/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prprprus%2Fgds/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prprprus%2Fgds/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prprprus","download_url":"https://codeload.github.com/prprprus/gds/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253850893,"owners_count":21973672,"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":["datastructures","go","golang","implement","implementation"],"created_at":"2024-11-06T10:28:16.562Z","updated_at":"2025-05-13T00:54:04.264Z","avatar_url":"https://github.com/prprprus.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![build status](https://travis-ci.org/prprprus/ds.svg?branch=master)\n[![go report](https://goreportcard.com/badge/github.com/prprprus/ds)](https://goreportcard.com/report/github.com/prprprus/ds)\n[![godoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/prprprus/ds)\n[![license](https://img.shields.io/badge/license-license-yellow.svg)](https://github.com/prprprus/ds/blob/master/LICENSE)\n[![](https://img.shields.io/badge/EN-%E8%8B%B1%E6%96%87-%09%236495ED.svg)](./README.md)\n\n## 介绍\n\n用 Go 实现数据结构。\n\n## 目录\n\n- [Iterator](#iterator)\n  - [ValueIterator](#valueIterator)\n  - [ReverseValueIterator](#reverseValueIterator)\n  - [IndexIterator](#indexIterator)\n  - [ReverseIndexIterator](#reverseIndexIterator)\n  - [KeyIterator](#keyIterator)\n  - [ReverseKeyIterator](#reverseKeyIterator)\n- [Container](#container)\n  - [List](#list)\n    - [SinglyLinkedList](#singlylinkedlist)\n    - [DoubleLinkedList](#DoubleLinkedList)\n    - [ArrayList](#ArrayList)\n  - [Stack](#Stack)\n    - [LinkedListStack](#LinkedListStack)\n    - [ArrayStack](#ArrayStack)\n  - [Queue](#Queue)\n    - [LinkedListQueue](#LinkedListQueue)\n    - [ArrayQueue](#ArrayQueue)\n  - [SkipList](#SkipList)\n  - [Map](#Map)\n    - [HashMap](#HashMap)\n    - [LinkedHashMap](#LinkedHashMap)\n    - [SkipMap](#SkipMap)\n  - [Set](#Set)\n    - [HashSet](#HashSet)\n    - [LinkedHashSet](#LinkedHashSet)\n    - [SkipSet](#SkipSet)\n- [Util](#Util)\n  - [Comparator](#Comparator)\n- [Benchmarking](#Benchmarking)\n\n## Iterator\n\n### ValueIterator\n\n提供了 6 种迭代器，如下。\n\n`ValueIterator` 向后遍历值。\n\n```go\ntype ValueIterator interface {\n\tNext() bool\n\tBegin()\n\tValue() interface{}\n}\n```\n\n### ReverseValueIterator\n\n`ReverseValueIterator` 可以向前或者向后遍历值。\n\n```go\ntype ReverseValueIterator interface {\n\tValueIterator\n\n\tPrev() bool\n\tEnd()\n}\n```\n\n### IndexIterator\n\n`IndexIterator` 向后遍历索引和值。\n\n```go\ntype IndexIterator interface {\n\tValueIterator\n\n\tIndex() int\n}\n```\n\n### ReverseIndexIterator\n\n`ReverseIndexIterator` 可以向前或者向后遍历索引和值。\n\n```go\ntype ReverseIndexIterator interface {\n\tIndexIterator\n\n\tPrev() bool\n\tEnd()\n}\n```\n\n### KeyIterator\n\n`KeyIterator` 向后遍历键值对。\n\n```go\ntype KeyIterator interface {\n\tValueIterator\n\n\tKey() interface{}\n}\n```\n\n### ReverseKeyIterator\n\n`ReverseKeyIterator` 可以向前或者向后遍历键值对。\n\n```go\ntype ReverseKeyIterator interface {\n\tKeyIterator\n\n\tPrev() bool\n\tEnd()\n}\n```\n\n不同的数据结构对迭代器的支持是不同的，如下。\n\n![ds1.png](https://i.loli.net/2019/09/21/mvktdhMKD9g8oSy.png)\n\n## Container\n\n所有的数据结构都会实现 Container 接口。\n\n```go\ntype Container interface {\n\tEmpty() bool\n\tSize() int\n\tClear()\n\tValues() []interface{}\n}\n```\n\n### List\n\n`List` 是有序的，而且值可以重复。\n\n实现了 [Container](#container) 接口。\n\n```go\ntype List interface {\n\tAppend(values ...interface{})\n\tGet(index int) (interface{}, error)\n\tRemove(index int) error\n\tContains(values ...interface{}) bool\n\tSwap(i, j int) error\n\tInsert(index int, values ...interface{}) error\n\tSet(index int, value interface{}) error\n\tIndexOf(value interface{}) (int, error)\n\n\tcontainer.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n}\n```\n\n#### SinglyLinkedList\n\n`SinglyLinkedList` 的当前元素会指向下一个元素。\n\n实现了 [List](#list), [ValueIterator](#ValueIterator) and [IndexIterator](#indexIterator) 接口。\n\n\u003cimg src=\"https://raw.githubusercontent.com/prprprus/picture/master/ds13.png\" alt=\"drawing\" width=\"300\"/\u003e\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/list/singlylinkedlist\"\n)\n\nfunc main() {\n\tlist := singlylinkedlist.New() // []\n\tlist.Append(1)                 // [1]\n\tlist.Append(2)                 // [1, 2]\n\tlist.Append(3)                 // [1, 2, 3]\n\tlist.PreAppend(4)              // [4, 1, 2, 3]\n\t_, _ = list.Get(0)             // 4, nil\n\t_, _ = list.Get(999)           // nil, ErrIndex\n\t_ = list.Remove(2)             // [4, 1, 3]\n\t_ = list.Contains()            // true\n\t_ = list.Contains(4, 1)        // true\n\t_ = list.Contains(4, 3)        // true\n\t_ = list.Contains(4, 1, 3, 5)  // false\n\t_ = list.Swap(0, 1)            // [1, 4, 3]\n\t_ = list.Insert(1, 5, 6, 7, 8) // [1, 4, 5, 6, 7, 8, 3]\n\t_ = list.Set(3, -1)            // [1, 4, 5, -1, 7, 8, 3]\n\n\t// iterator\n\tit := list.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// 0 1\n\t// 1 4\n\t// 2 5\n\t// 3 -1\n\t// 4 7\n\t// 5 8\n\t// 6 3\n\n\t_, _ = list.IndexOf(1)   // 0, nil\n\t_, _ = list.IndexOf(8)   // 5, nil\n\t_, _ = list.IndexOf(100) // -1, ErrIndexOf\n\tlist.Reverse()           // [3, 8, 7, -1, 5, 4, 1]\n\t_ = list.Empty()         // false\n\t_ = list.Size()          // 7\n\t_ = list.Values()        // [3 8 7 -1 5 4 1]\n\tlist.Clear()             // []\n}\n```\n\n#### DoubleLinkedList\n\n`DoubleLinkedList` 的当前元素和下一个元素之间相互指向。\n\n实现了 [List](#list), [ValueIterator](#ValueIterator), [ReverseValueIterator](#ReverseValueIterator), [IndexIterator](#IndexIterator) and [ReverseIndexIterator](#ReverseIndexIterator) 接口。\n\n\u003cimg src=\"https://raw.githubusercontent.com/prprprus/picture/master/ds14.png\" alt=\"drawing\" width=\"450\"/\u003e\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/list/doublelinkedlist\"\n)\n\nfunc main() {\n\tlist := doublelinkedlist.New() // []\n\tlist.Append(1)                 // [1]\n\tlist.Append(2)                 // [1 2]\n\tlist.Append(3)                 // [1 2 3]\n\tlist.PreAppend(4)              // [4 1 2 3]\n\t_, _ = list.Get(0)             // 4, nil\n\t_, _ = list.Get(999)           // nil, ErrIndex\n\t_ = list.Remove(2)             // [4 1 3]\n\t_ = list.Contains()            // true\n\t_ = list.Contains(4, 1)        // true\n\t_ = list.Contains(4, 3)        // true\n\t_ = list.Contains(4, 1, 3, 5)  // false\n\t_ = list.Swap(0, 1)            // [1 4 3]\n\t_ = list.Insert(1, 5, 6, 7, 8) // [1 4 5 6 7 8 3]\n\t_ = list.Set(3, -1)            // [1 4 5 -1 7 8 3]\n\n\t// iterator\n\tit := list.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// 0 1\n\t// 1 4\n\t// 2 5\n\t// 3 -1\n\t// 4 7\n\t// 5 8\n\t// 6 3\n\tit.End()\n\tfor it.Prev() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// 6 3\n\t// 5 8\n\t// 4 7\n\t// 3 -1\n\t// 2 5\n\t// 1 4\n\t// 0 1\n\n\t_, _ = list.IndexOf(1)   // 0, nil\n\t_, _ = list.IndexOf(8)   // 5, nil\n\t_, _ = list.IndexOf(100) // -1, ErrIndexOf\n\tlist.Reverse()           // [3 8 7 -1 5 4 1]\n\t_ = list.Empty()         // false\n\t_ = list.Size()          // 7\n\t_ = list.Values()        // [3 8 7 -1 5 4 1]\n\tlist.Clear()             // []\n}\n```\n\n#### ArrayList\n\n`ArrayList` 是一种动态数组，可以根据容量和元素个数之间的比例动态伸缩。\n\n实现了 [List](#list), [ValueIterator](#ValueIterator), [ReverseValueIterator](#ReverseValueIterator), [IndexIterator](#IndexIterator) and [ReverseIndexIterator](#ReverseIndexIterator) 接口。\n\n\u003cimg src=\"https://raw.githubusercontent.com/prprprus/picture/master/ds17.png\" alt=\"drawing\" width=\"300\"/\u003e\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/list/arraylist\"\n)\n\nfunc main() {\n\tlist := arraylist.New()        // []\n\tlist.Append(1)                 // [1]\n\tlist.Append(2)                 // [1 2]\n\tlist.Append(3)                 // [1 2 3]\n\t_, _ = list.Get(0)             // 1, nil\n\t_, _ = list.Get(999)           // nil, ErrIndex\n\t_ = list.Remove(2)             // [1 2]\n\t_ = list.Contains()            // true\n\t_ = list.Contains(1, 2)        // true\n\t_ = list.Contains(2)           // true\n\t_ = list.Contains(1, 2, 3)     // false\n\t_ = list.Swap(0, 1)            // [2 1]\n\t_ = list.Insert(1, 5, 6, 7, 8) // [2 1 5 6 7 8]\n\t_ = list.Set(3, -1)            // [2 1 5 -1 7 8]\n\n\t// iterator\n\tit := list.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// 0 2\n\t// 1 1\n\t// 2 5\n\t// 3 -1\n\t// 4 7\n\t// 5 8\n\tit.End()\n\tfor it.Prev() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// \t5 8\n\t// 4 7\n\t// 3 -1\n\t// 2 5\n\t// 1 1\n\t// 0 2\n\n\t_, _ = list.IndexOf(1)   // 1, nil\n\t_, _ = list.IndexOf(8)   // 5, nil\n\t_, _ = list.IndexOf(100) // -1, ErrIndexOf\n\t_ = list.Empty()         // false\n\t_ = list.Size()          // 6\n\t_ = list.Values()        // [2 1 5 -1 7 8]\n\tlist.Clear()             // []\n}\n```\n\n### Stack\n\n`Stack` 是一种先进后出的数据结构。\n\n实现了 [Container](#container) 接口。\n\n\u003cimg src=\"https://raw.githubusercontent.com/prprprus/picture/master/ds15.png\" alt=\"drawing\" width=\"500\"/\u003e\n\n```go\ntype Stack interface {\n\tPush(value interface{})\n\tPop() (interface{}, error)\n\tPeek() (interface{}, error)\n\n\tcontainer.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n}\n```\n\n#### LinkedListStack\n\n`LinkedListStack` 是基于 [SinglyLinkedList](#SinglyLinkedList) 实现的栈。\n\n实现了 [Stack](#Stack), [ValueIterator](#ValueIterator) and [IndexIterator](#IndexIterator) 接口。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/stack/linkedliststack\"\n)\n\nfunc main() {\n\tstack := linkedliststack.New() // []\n\tstack.Push(1)                  // [1]\n\tstack.Push(2)                  // [2 1]\n\tstack.Push(3)                  // [3 2 1]\n\n\t// iterator\n\tit := stack.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// 0 3\n\t// 1 2\n\t// 2 1\n\n\t_, _ = stack.Peek() // 3, nil\n\t_, _ = stack.Pop()  // 3, nil\n\t_, _ = stack.Peek() // 2, nil\n\t_ = stack.Empty()   // false\n\t_ = stack.Size()    // 2\n\t_ = stack.Values()  // [2 1]\n\tstack.Clear()       // []\n}\n```\n\n#### ArrayStack\n\n`ArrayStack` 是基于 [ArrayList](#ArrayList) 实现的栈。\n\n实现了 [Stack](#Stack), [ValueIterator](#ValueIterator), [ReverseValueIterator](#ReverseValueIterator), [IndexIterator](#IndexIterator) and [ReverseIndexIterator](#ReverseIndexIterator) 接口。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/stack/arraystack\"\n)\n\nfunc main() {\n\tstack := arraystack.New() // []\n\tstack.Push(1)             // [1]\n\tstack.Push(2)             // [2 1]\n\tstack.Push(3)             // [3 2 1]\n\n\t// iterator\n\tit := stack.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// 0 3\n\t// 1 2\n\t// 2 1\n\n\t_, _ = stack.Peek() // 3, nil\n\t_, _ = stack.Pop()  // 3, nil\n\t_, _ = stack.Peek() // 2, nil\n\t_ = stack.Empty()   // false\n\t_ = stack.Size()    // 2\n\t_ = stack.Values()  // [2 1]\n\tstack.Clear()       // []\n}\n```\n\n### Queue\n\n`Queue` 是一种先进先出的数据结构。\n\n实现了 [Container](#container) 接口。\n\n\u003cimg src=\"https://raw.githubusercontent.com/prprprus/picture/master/ds16.png\" alt=\"drawing\" width=\"300\"/\u003e\n\n```go\ntype Queue interface {\n\tPut(value interface{})\n\tGet() (interface{}, error)\n\n\tcontainer.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n}\n```\n\n#### LinkedListQueue\n\n`LinkedListQueue` 是基于 [SinglyLinkedList](#SinglyLinkedList) 实现的队列。\n\n实现了 [Queue](#Queue), [ValueIterator](#ValueIterator) and [IndexIterator](#IndexIterator) 接口。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/queue/linkedlistqueue\"\n)\n\nfunc main() {\n\tqueue := linkedlistqueue.New() // []\n\tqueue.Put(1)                   // [1]\n\tqueue.Put(2)                   // [1 2]\n\tqueue.Put(3)                   // [1 2 3]\n\tqueue.Put(4)                   // [1 2 3 4]\n\n\t// iterator\n\tit := queue.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// 0 1\n\t// 1 2\n\t// 2 3\n\t// 3 4\n\n\t_, _ = queue.Get() // 1, nil\n\t_, _ = queue.Get() // 2, nil\n\t_ = queue.Empty()  // false\n\t_ = queue.Size()   // 2\n\t_ = queue.Values() // [3 4]\n\tqueue.Clear()      // []\n}\n```\n\n#### ArrayQueue\n\n`ArrayQueue` 是基于 [ArrayList](#ArrayList) 实现的队列。\n\n实现了 [Queue](#Queue), [ValueIterator](#ValueIterator) and [IndexIterator](#IndexIterator) 接口。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/queue/arrayqueue\"\n)\n\nfunc main() {\n\tqueue := arrayqueue.New() // []\n\tqueue.Put(1)              // [1]\n\tqueue.Put(2)              // [1 2]\n\tqueue.Put(3)              // [1 2 3]\n\tqueue.Put(4)              // [1 2 3 4]\n\n\t// iterator\n\tit := queue.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Index(), it.Value())\n\t}\n\t// output:\n\t// 0 1\n\t// 1 2\n\t// 2 3\n\t// 3 4\n\n\t_, _ = queue.Get() // 1, nil\n\t_, _ = queue.Get() // 2, nil\n\t_ = queue.Empty()  // false\n\t_ = queue.Size()   // 2\n\t_ = queue.Values() // [3 4]\n\tqueue.Clear()      // []\n}\n```\n\n### SkipList\n\n`SkipList` 是一种带有随机性的数据结构，它的性能可以和红黑树媲美。需要注意的是，键必须是可以比较的类型。\n\n实现了 [Container](#container), [ValueIterator](#ValueIterator) and [KeyIterator](#KeyIterator) 接口。\n\n\u003cimg src=\"https://raw.githubusercontent.com/prprprus/picture/master/ds2.png\" alt=\"drawing\" width=\"550\"/\u003e\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/skiplist\"\n\t\"github.com/prprprus/ds/util\"\n)\n\nfunc main() {\n\tskiplist := skiplist.New(util.IntComparator) // []\n\tskiplist.Set(1, \"a\")                         // [{1: \"a\"}]\n\tskiplist.Set(2, \"b\")                         // [{1: \"a\"} {2: \"b\"}]\n\tskiplist.Set(3, \"c\")                         // [{1: \"a\"} {2: \"b\"} {3: \"c\"}]\n\tskiplist.Set(4, \"d\")                         // [{1: \"a\"} {2: \"b\"} {3: \"c\"} {4: \"d\"}]\n\n\t// iterator\n\tit := skiplist.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Key(), it.Value())\n\t}\n\t// output:\n\t// 1 a\n\t// 2 b\n\t// 3 c\n\t// 4 d\n\n\t_ = skiplist.Exists(1) // true\n\t_ = skiplist.Exists(9) // false\n\t_, _ = skiplist.Get(1) // \"a\", nil\n\t_, _ = skiplist.Get(3) // \"c\", nil\n\t_ = skiplist.Remove(2) // nil\n\t_ = skiplist.Keys()    // [1 3 4]\n\t_ = skiplist.Empty()   // false\n\t_ = skiplist.Size()    // 3\n\t_ = skiplist.Values()  // [a c d]\n\tskiplist.Clear()       // []\n}\n```\n\n### Map\n\n`Map` 用于存储键值对，拥有出色的性能。需要注意的是，键必须是可以比较的类型。\n\n实现了 [Container](#container) 接口。\n\n```go\ntype Map interface {\n\tPut(key, value interface{})\n\tGet(key interface{}) (interface{}, error)\n\tRemove(key interface{})\n\n\tcontainer.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n}\n```\n\n#### HashMap\n\n`HashMap` 是基于哈希表实现的 map。\n\n实现了 [Map](#Map) 接口。\n\n\u003cimg src=\"https://raw.githubusercontent.com/prprprus/picture/master/ds18.png\" alt=\"drawing\" width=\"400\"/\u003e\n\n```go\npackage main\n\nimport (\n\t\"github.com/prprprus/ds/maps/hashmap\"\n)\n\nfunc main() {\n\tm := hashmap.New() // []\n\tm.Put(1, \"a\")      // [{1: \"a\"}]\n\tm.Put(2, \"b\")      // [{1: \"a\"} {2: \"b\"}]\n\tm.Put(3, \"c\")      // [{1: \"a\"} {2: \"b\"} {3: \"c\"}]\n\tm.Put(4, \"d\")      // [{1: \"a\"} {2: \"b\"} {3: \"c\"} {4: \"d\"}]\n\t_ = m.Keys()       // [1 2 3 4] (Note: order of random)\n\t_, _ = m.Get(1)    // \"a\", nil\n\t_, _ = m.Get(3)    // \"c\", nil\n\t_ = m.Remove(2)    // nil\n\t_ = m.Keys()       // [1 3 4]\n\t_ = m.Empty()      // false\n\t_ = m.Size()       // 3\n\t_ = m.Values()     // [a c d] (Note: order of random)\n\tm.Clear()          // []\n}\n```\n\n#### LinkedHashMap\n\n`LinkedHashMap` 是基于哈希表和 [DoubleLinkedList](#DoubleLinkedList) 实现的 map，它提供了额外的有序键值对。\n\n实现了 [Map](#Map), [ValueIterator](#ValueIterator), [ReverseValueIterator](#ReverseValueIterator), [KeyIterator](#KeyIterator) and [ReverseKeyIterator](#ReverseKeyIterator) 接口。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/maps/linkedhashmap\"\n)\n\nfunc main() {\n\tm := linkedhashmap.New() // []\n\tm.Put(1, \"a\")            // [{1: \"a\"}]\n\tm.Put(2, \"b\")            // [{1: \"a\"} {2: \"b\"}]\n\tm.Put(3, \"c\")            // [{1: \"a\"} {2: \"b\"} {3: \"c\"}]\n\tm.Put(4, \"d\")            // [{1: \"a\"} {2: \"b\"} {3: \"c\"} {4: \"d\"}]\n\n\t// iterator\n\tit := m.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Key(), it.Value())\n\t}\n\t// output:\n\t// 1 a\n\t// 2 b\n\t// 3 c\n\t// 4 d\n\tit.End()\n\tfor it.Prev() {\n\t\tfmt.Println(it.Key(), it.Value())\n\t}\n\t// output:\n\t// 4 d\n\t// 3 c\n\t// 2 b\n\t// 1 a\n\n\t_ = m.Keys()    // [1 2 3 4]\n\t_, _ = m.Get(1) // \"a\", nil\n\t_, _ = m.Get(3) // \"c\", nil\n\t_ = m.Remove(2) // nil\n\t_ = m.Keys()    // [1 3 4]\n\t_ = m.Empty()   // false\n\t_ = m.Size()    // 3\n\t_ = m.Values()  // [a c d]\n\tm.Clear()       // []\n}\n```\n\n#### SkipMap\n\n`SkipMap` 是基于 [SkipList](#SkipList) 实现的 map。\n\n实现了 [Map](#Map), [ValueIterator](#ValueIterator) and [KeyIterator](#KeyIterator) 接口。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/maps/linkedhashmap\"\n)\n\nfunc main() {\n\tm := linkedhashmap.New() // []\n\tm.Put(1, \"a\")            // [{1: \"a\"}]\n\tm.Put(2, \"b\")            // [{1: \"a\"} {2: \"b\"}]\n\tm.Put(3, \"c\")            // [{1: \"a\"} {2: \"b\"} {3: \"c\"}]\n\tm.Put(4, \"d\")            // [{1: \"a\"} {2: \"b\"} {3: \"c\"} {4: \"d\"}]\n\n\t// iterator\n\tit := m.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Key(), it.Value())\n\t}\n\t// output:\n\t// 1 a\n\t// 2 b\n\t// 3 c\n\t// 4 d\n\n\t_ = m.Keys()    // [1 2 3 4]\n\t_, _ = m.Get(1) // \"a\", nil\n\t_, _ = m.Get(3) // \"c\", nil\n\t_ = m.Remove(2) // nil\n\t_ = m.Keys()    // [1 3 4]\n\t_ = m.Empty()   // false\n\t_ = m.Size()    // 3\n\t_ = m.Values()  // [a c d]\n\tm.Clear()       // []\n}\n```\n\n### Set\n\n`Set` 用于存储不可重复的值，通常也拥有出色的性能。\n\n实现了 [Container](#container) 接口。\n\n```go\ntype Set interface {\n\tAdd(values ...interface{})\n\tRemove(values ...interface{}) error\n\tContains(values ...interface{}) bool\n\n\tcontainer.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n}\n```\n\n#### HashSet\n\n`HashSet` 是基于哈希表实现的 set。\n\n实现了 [Set](#Set) 接口。\n\n```go\npackage main\n\nimport (\n\t\"github.com/prprprus/ds/set/hashset\"\n)\n\nfunc main() {\n\ts := hashset.New()      // []\n\ts.Add(1)                // [1]\n\ts.Add(2)                // [1 2]\n\ts.Add(3)                // [1 2 3]\n\t_ = s.Contains()        // true\n\t_ = s.Contains(1, 2, 3) // true\n\t_ = s.Contains(1, 3)    // true\n\t_ = s.Contains(2, 3, 4) // false\n\t_ = s.Remove(2)         // nil\n\t_ = s.Empty()           // false\n\t_ = s.Size()            // 2\n\t_ = s.Values()          // [1 3]\n\ts.Clear()               // []\n}\n```\n\n#### LinkedHashSet\n\n`LinkedHashSet` 是基于哈希表和 [DoubleLinkedList](#DoubleLinkedList) 实现的 set，它保证了值是有序的。\n\n实现了 [Set](#Set), [ValueIterator](#valueIterator) and [ReverseValueIterator](#reverseValueIterator) 接口。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/set/linkedhashset\"\n)\n\nfunc main() {\n\ts := linkedhashset.New() // []\n\ts.Add(1)                 // [1]\n\ts.Add(2)                 // [1 2]\n\ts.Add(3)                 // [1 2 3]\n\n\t// iterator\n\tit := s.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Value())\n\t}\n\t// output:\n\t// 1\n\t// 2\n\t// 3\n\tit.End()\n\tfor it.Prev() {\n\t\tfmt.Println(it.Value())\n\t}\n\t// output:\n\t// 3\n\t// 2\n\t// 1\n\n\t_ = s.Contains()        // true\n\t_ = s.Contains(1, 2, 3) // true\n\t_ = s.Contains(1, 3)    // true\n\t_ = s.Contains(2, 3, 4) // false\n\t_ = s.Remove(2)         // nil\n\t_ = s.Empty()           // false\n\t_ = s.Size()            // 2\n\t_ = s.Values()          // [1 3]\n\ts.Clear()               // []\n}\n```\n\n#### SkipSet\n\n`SkipSet` 是基于 [SkipList](#SkipList) 实现的 set。\n\n实现了 [Set](#Set) and [ValueIterator](#valueIterator) 接口。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prprprus/ds/set/skipset\"\n\t\"github.com/prprprus/ds/util\"\n)\n\nfunc main() {\n\ts := skipset.New(util.IntComparator) // []\n\ts.Add(1)                             // [1]\n\ts.Add(2)                             // [1 2]\n\ts.Add(3)                             // [1 2 3]\n\n\t// iterator\n\tit := s.Iterator()\n\tit.Begin()\n\tfor it.Next() {\n\t\tfmt.Println(it.Value())\n\t}\n\t// output:\n\t// 1\n\t// 2\n\t// 3\n\n\t_ = s.Contains()        // true\n\t_ = s.Contains(1, 2, 3) // true\n\t_ = s.Contains(1, 3)    // true\n\t_ = s.Contains(2, 3, 4) // false\n\t_ = s.Remove(2)         // nil\n\t_ = s.Empty()           // false\n\t_ = s.Size()            // 2\n\t_ = s.Values()          // [1 3]\n\ts.Clear()               // []\n}\n```\n\n## Util\n\n包含一些辅助函数。\n\n### Comparator\n\n提供了用于内置类型的比较器，如下。\n\n```go\nfunc IntComparator(a, b interface{}) int\n\nfunc Int8Comparator(a, b interface{}) int\n\nfunc Int16Comparator(a, b interface{}) int\n\nfunc Int32Comparator(a, b interface{}) int\n\nfunc Int64Comparator(a, b interface{}) int\n\nfunc UIntComparator(a, b interface{}) int\n\nfunc UInt8Comparator(a, b interface{}) int\n\nfunc UInt16Comparator(a, b interface{}) int\n\nfunc UInt32Comparator(a, b interface{}) int\n\nfunc UInt64Comparator(a, b interface{}) int\n\nfunc Float32Comparator(a, b interface{}) int\n\nfunc Float64Comparator(a, b interface{}) int\n\nfunc ByteComparator(a, b interface{}) int\n\nfunc RuneComparator(a, b interface{}) int\n\nfunc StringComparator(a, b interface{}) int\n```\n\n返回值的意义如下。\n\n```\n-1 =\u003e a \u003c b\n0  =\u003e a == b\n1  =\u003e a \u003e b\n```\n\n对于自定义类型，也可以创建相对应的比较器。\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n\n    \"github.com/prprprus/ds/set/skipset\"\n)\n\ntype People struct {\n    name string\n    age  int\n}\n\nfunc AgeComparator(a, b interface{}) int {\n    c1 := a.(People)\n    c2 := b.(People)\n    switch {\n\tcase c1.age \u003c c2.age:\n\t\treturn -1\n\tcase c1.age \u003e c2.age:\n\t\treturn 1\n\tdefault:\n\t\treturn 0\n\t}\n}\n\nfunc main() {\n    s := skipset.New(AgeComparator)\n    s.Add(People{\"Wade\", 35})\n    s.Add(People{\"Simon\", 32})\n    s.Add(People{\"yiyi\", 22})\n\n    fmt.Println(s.Values()) // [{\"yiyi\", 22}, {\"Simon\", 32}, {\"Wade\", 35}]\n}\n```\n\n## Benchmarking\n\n`go test -run=NO_TEST -bench=. -benchmem -benchtime 1s github.com/prprprus/ds/...`\n\n![ds-bench-1.png](https://i.loli.net/2019/09/21/ws3z1RWhm8yxYGC.png)\n![ds-bench-2.png](https://i.loli.net/2019/09/21/gI3wGazoBuAF4XQ.png)\n![ds-bench-3.png](https://i.loli.net/2019/09/21/hi9YLGUfX3DyzNE.png)\n![ds-bench-4.png](https://i.loli.net/2019/09/21/qGQ3yFdsevifCYm.png)\n![ds-bench-5.png](https://i.loli.net/2019/09/21/HfnzLDoImb1xGt6.png)\n![ds-bench-6.png](https://i.loli.net/2019/09/21/4c6s3NQJpzErWj1.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprprprus%2Fgds","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprprprus%2Fgds","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprprprus%2Fgds/lists"}