├── .gitignore ├── LICENSE ├── README.md ├── README_ZH.md ├── avlbetter.go ├── avltree.go ├── bench_test.go ├── example └── main.go ├── go.mod ├── gomap.go ├── gomap_test.go ├── queue.go ├── queue_test.go └── rbtree.go /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /xx 3 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Map Golang implement by Red-Black Tree, AVL Tree 2 | 3 | [![GitHub forks](https://img.shields.io/github/forks/hunterhug/gomap.svg?style=social&label=Forks)](https://github.com/hunterhug/gomap/network) 4 | [![GitHub stars](https://img.shields.io/github/stars/hunterhug/gomap.svg?style=social&label=Stars)](https://github.com/hunterhug/gomap/stargazers) 5 | [![GitHub last commit](https://img.shields.io/github/last-commit/hunterhug/gomap.svg)](https://github.com/hunterhug/gomap) 6 | [![GitHub issues](https://img.shields.io/github/issues/hunterhug/gomap.svg)](https://github.com/hunterhug/gomap/issues) 7 | 8 | [中文说明](/README_ZH.md) 9 | 10 | Map implement by tree data struct such Red-Black Tree, AVL Tree. 11 | 12 | Our tree map is design to be concurrent safe, and don't waste any space different from golang standard map which not shrink even map key pairs num is 0. 13 | 14 | ## Usage 15 | 16 | Simple get it by: 17 | 18 | ``` 19 | go get -v github.com/hunterhug/gomap 20 | ``` 21 | 22 | There are: 23 | 24 | 1. Standard Red-Black Tree Map(2-3-4-Tree): `gomap.New()`,`gomap.NewMap()`,`gomap.NewRBMap()`. 25 | 2. AVL Tree Map: `gomap.NewAVLMap()`. 26 | 27 | Core api: 28 | 29 | ```go 30 | // Map method 31 | // design to be concurrent safe 32 | type Map interface { 33 | Put(key string, value interface{}) // put key pairs 34 | Delete(key string) // delete a key 35 | Get(key string) (value interface{}, exist bool) // get value from key 36 | GetInt(key string) (value int, exist bool, err error) // get value auto change to Int 37 | GetInt64(key string) (value int64, exist bool, err error) // get value auto change to Int64 38 | GetString(key string) (value string, exist bool, err error) // get value auto change to string 39 | GetFloat64(key string) (value float64, exist bool, err error) // get value auto change to string 40 | GetBytes(key string) (value []byte, exist bool, err error) // get value auto change to []byte 41 | Contains(key string) (exist bool) // map contains key? 42 | Len() int64 // map key pairs num 43 | KeyList() []string // map key out to list from top to bottom which is layer order 44 | KeySortedList() []string // map key out to list sorted 45 | Iterator() MapIterator // map iterator, iterator from top to bottom which is layer order 46 | MaxKey() (key string, value interface{}, exist bool) // find max key pairs 47 | MinKey() (key string, value interface{}, exist bool) // find min key pairs 48 | SetComparator(comparator) Map // set compare func to control key compare 49 | } 50 | 51 | // Iterator concurrent not safe 52 | // you should deal by yourself 53 | type MapIterator interface { 54 | HasNext() bool 55 | Next() (key string, value interface{}) 56 | } 57 | ``` 58 | 59 | We has already implement them by non recursion way and optimized a lot, so use which type of tree map is no different. 60 | 61 | ## Example 62 | 63 | Some example below: 64 | 65 | ```go 66 | package main 67 | 68 | import ( 69 | "fmt" 70 | "github.com/hunterhug/gomap" 71 | "math/rand" 72 | "strconv" 73 | "time" 74 | ) 75 | 76 | // loop times 77 | // 循环的次数,用于随机添加和删除键值对 78 | // 可以修改成1000 79 | var num = 20 80 | 81 | func init() { 82 | // random seed 83 | // 随机数种子初始化 84 | rand.Seed(time.Now().Unix()) 85 | } 86 | 87 | // diy comparator 88 | // 内部是按键字符串来做查找树,我们把他变成整形 89 | func comparatorInt(key1, key2 string) int64 { 90 | k1, _ := strconv.Atoi(key1) 91 | k2, _ := strconv.Atoi(key2) 92 | if k1 == k2 { 93 | return 0 94 | } else if k1 > k2 { 95 | return 1 96 | } else { 97 | return -1 98 | } 99 | } 100 | 101 | func main() { 102 | checkMap := make(map[string]struct{}) 103 | 104 | // 1. new a map default is rb tree 105 | // 1. 新建一个 Map,默认为标准红黑树实现 106 | m := gomap.New() 107 | //m = gomap.NewAVLMap() // avl tree better version 108 | //m = gomap.NewAVLRecursionMap() // avl tree bad version 109 | 110 | m.SetComparator(comparatorInt) // set inner comparator 111 | 112 | for i := 0; i < num; i++ { 113 | key := fmt.Sprintf("%d", rand.Int63n(int64(num))) 114 | fmt.Println("add key:", key) 115 | checkMap[key] = struct{}{} 116 | 117 | // 2. put key pairs 118 | // 2. 放键值对 119 | m.Put(key, key) 120 | } 121 | 122 | fmt.Println("map len is ", m.Len()) 123 | 124 | // 3. can iterator 125 | // 3. 迭代器使用 126 | iterator := m.Iterator() 127 | for iterator.HasNext() { 128 | k, v := iterator.Next() 129 | fmt.Printf("Iterator key:%s,value %v\n", k, v) 130 | } 131 | 132 | // 4. get key 133 | // 4. 获取键中的值 134 | key := "9" 135 | value, exist := m.Get(key) 136 | if exist { 137 | fmt.Printf("%s exist, value is:%s\n", key, value) 138 | } else { 139 | fmt.Printf("%s not exist\n", key) 140 | } 141 | 142 | // 5. get int will err 143 | // 5. 获取键中的值,并且指定类型,因为类型是字符串,所以转成整形会报错 144 | _, _, err := m.GetInt(key) 145 | if err != nil { 146 | fmt.Println(err.Error()) 147 | } 148 | 149 | // 6. check is a rb tree 150 | // 6. 内部辅助,检查是不是一颗正常的红黑树 151 | if m.Check() { 152 | fmt.Println("is a rb tree,len:", m.Len()) 153 | } 154 | 155 | // 7. delete '9' then find '9' 156 | // 7. 删除键 '9' 然后再找 '9' 157 | m.Delete(key) 158 | value, exist = m.Get(key) 159 | if exist { 160 | fmt.Printf("%s exist, value is:%s\n", key, value) 161 | } else { 162 | fmt.Printf("%s not exist\n", key) 163 | } 164 | 165 | // 8. key list 166 | // 8. 获取键列表 167 | fmt.Printf("keyList:%#v,len:%d\n", m.KeyList(), m.Len()) 168 | fmt.Printf("keySortList:%#v,len:%d\n", m.KeySortedList(), m.Len()) 169 | 170 | // 9. delete many 171 | // 9. 删除很多键值对 172 | for key := range checkMap { 173 | v, ok := m.Get(key) 174 | fmt.Printf("find %s:%v=%v, delete key:%s\n", key, v, ok, key) 175 | m.Delete(key) 176 | if !m.Check() { 177 | fmt.Println("is not a rb tree,len:", m.Len()) 178 | } 179 | } 180 | 181 | // 10. key list 182 | // 10. 获取键列表 183 | fmt.Printf("keyList:%#v,len:%d\n", m.KeyList(), m.Len()) 184 | fmt.Printf("keySortList:%#v,len:%d\n", m.KeySortedList(), m.Len()) 185 | 186 | // 11. check is a rb tree 187 | // 11. 再次检查是否是一颗正常的红黑树 188 | if m.Check() { 189 | fmt.Println("is a rb tree,len:", m.Len()) 190 | } 191 | } 192 | ``` 193 | 194 | ## BenchTest 195 | 196 | We test `Golang map` and `Red-Black Tree`, `AVL Tree`: 197 | 198 | ```go 199 | go test -run="bench_test.go" -test.bench=".*" -test.benchmem=1 -count=1    master  200 | goos: darwin 201 | goarch: amd64 202 | pkg: github.com/hunterhug/gomap 203 | BenchmarkGolangMapPut-12 1791264 621 ns/op 112 B/op 6 allocs/op 204 | BenchmarkRBTMapPut-12 1000000 1408 ns/op 104 B/op 6 allocs/op 205 | BenchmarkAVLMapPut-12 1000000 1440 ns/op 104 B/op 6 allocs/op 206 | BenchmarkAVLRecursionMapPut-12 1000000 2024 ns/op 104 B/op 6 allocs/op 207 | BenchmarkGolangMapDelete-12 3577232 303 ns/op 15 B/op 1 allocs/op 208 | BenchmarkRBTMapDelete-12 996924 1248 ns/op 15 B/op 1 allocs/op 209 | BenchmarkAVLMapDelete-12 1000000 1227 ns/op 15 B/op 1 allocs/op 210 | BenchmarkAVLRecursionMapDelete-12 667242 1866 ns/op 15 B/op 1 allocs/op 211 | BenchmarkGolangMapGet-12 15797131 72.2 ns/op 2 B/op 1 allocs/op 212 | BenchmarkRBTMapGet-12 5798295 195 ns/op 2 B/op 1 allocs/op 213 | BenchmarkAVLMapGet-12 5831353 197 ns/op 2 B/op 1 allocs/op 214 | BenchmarkAVLRecursionMapGet-12 5275490 228 ns/op 2 B/op 1 allocs/op 215 | BenchmarkGolangMapRandom-12 1256779 940 ns/op 146 B/op 8 allocs/op 216 | BenchmarkRBTMapRandom-12 965804 2652 ns/op 126 B/op 8 allocs/op 217 | BenchmarkAVLMapRandom-12 902004 2805 ns/op 126 B/op 8 allocs/op 218 | BenchmarkAVLRecursionMapRandom-12 701880 3309 ns/op 129 B/op 8 allocs/op 219 | PASS 220 | ok github.com/hunterhug/gomap 66.006s 221 | ``` 222 | 223 | If you want to save memory space, you can choose our tree map. 224 | 225 | # License 226 | 227 | ``` 228 | Copyright [2019-2021] [github.com/hunterhug] 229 | 230 | Licensed under the Apache License, Version 2.0 (the "License"); 231 | you may not use this file except in compliance with the License. 232 | You may obtain a copy of the License at 233 | 234 | http://www.apache.org/licenses/LICENSE-2.0 235 | 236 | Unless required by applicable law or agreed to in writing, software 237 | distributed under the License is distributed on an "AS IS" BASIS, 238 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 239 | See the License for the specific language governing permissions and 240 | limitations under the License. 241 | ``` -------------------------------------------------------------------------------- /README_ZH.md: -------------------------------------------------------------------------------- 1 | # Tree Map,使用红黑树,AVL树实现 2 | 3 | [![GitHub forks](https://img.shields.io/github/forks/hunterhug/gomap.svg?style=social&label=Forks)](https://github.com/hunterhug/gomap/network) 4 | [![GitHub stars](https://img.shields.io/github/stars/hunterhug/gomap.svg?style=social&label=Stars)](https://github.com/hunterhug/gomap/stargazers) 5 | [![GitHub last commit](https://img.shields.io/github/last-commit/hunterhug/gomap.svg)](https://github.com/hunterhug/gomap) 6 | [![GitHub issues](https://img.shields.io/github/issues/hunterhug/gomap.svg)](https://github.com/hunterhug/gomap/issues) 7 | 8 | [English README](/README.md) 9 | 10 | 哈希表在某些场景下可以称为字典,用途是可以根据 `键key` 索引该键对应的 `值value`。哈希表是什么,可以参考:[数据结构和算法(Golang实现)](https://github.com/hunterhug/goa.c)。 11 | 12 | 我们知道 `Golang map`,内置类型的 `map` 使用拉链法实现,会提前分配空间,随着元素的增加,会不断扩容,这样会一直占用空间,即使删除元素也不会缩容,导致无法垃圾回收,可能出现内存溢出的情况。 13 | 14 | 我们使用平衡二叉查找树:红黑树或者AVL树来实现 `map`,不会占用多余空间,因为 `Golang` 不支持范型,目前 `key` 必须是字符串,`value` 可以是任何类型,且为了效率,我们不进行哈希处理,也就是 `键key` 的 `hash` 就是其本身。 15 | 16 | ## 如何使用 17 | 18 | 很简单,执行: 19 | 20 | ``` 21 | go get -v github.com/hunterhug/gomap 22 | ``` 23 | 24 | 目前 `gomap` 支持并发安全,并且可选多种平衡二叉查找树。 25 | 26 | 有以下几种用法: 27 | 28 | 1. `Red-Black Tree`,使用标准红黑树(2-3-4-树): `gomap.New()`,`gomap.NewMap()`,`gomap.NewRBMap()`。 29 | 2. `AVL Tree`,使用AVL树: `gomap.NewAVLMap()`。 30 | 31 | 以上实现都是非递归版本,性能有保证。 32 | 33 | 核心 API: 34 | 35 | ```go 36 | // Tree Map 实现 37 | // 被设计为并发安全的 38 | type Map interface { 39 | Put(key string, value interface{}) // 放入键值对 40 | Delete(key string) // 删除键 41 | Get(key string) (interface{}, bool) // 获取键,返回的值 value 是 interface{} 类型的,想返回具体类型的值参考下面的方法 42 | GetInt(key string) (int, bool, error) // 获取键,返回的值 value 转成 int 43 | GetInt64(key string) (int64, bool, error) // 获取键,返回的值 value 转成 int64 44 | GetString(key string) (string, bool, error) // 获取键,返回的值 value 转成 string 45 | GetFloat64(key string) (float64, bool, error) // 获取键,返回的值 value 转成 float64 46 | GetBytes(key string) ([]byte, bool, error) // 获取键,返回的值 value 转成 []byte 47 | Contains(key string) bool // 查看键是否存在 48 | Len() int64 // 查看键值对数量 49 | KeyList() []string // 根据树的层次遍历,获取键列表 50 | KeySortedList() []string // 根据树的中序遍历,获取字母序排序的键列表 51 | Iterator() MapIterator // 迭代器,实现迭代 52 | SetComparator(comparator) Map // 可自定义键比较器,默认按照字母序 53 | } 54 | 55 | // Iterator 迭代器,不是并发安全,迭代的时候确保不会修改Map,否则可能panic或产生副作用 56 | type MapIterator interface { 57 | HasNext() bool // 是否有下一对键值对 58 | Next() (key string, value interface{}) // 获取下一对键值对,迭代器向前一步 59 | } 60 | ``` 61 | 62 | ## 算法比较 63 | 64 | `Red-Black Tree` 添加操作最多旋转两次,删除操作最多旋转三次,树最大高度为 `2log(N+1)`。 65 | 66 | `AVL Tree` 添加操作最多旋转两次,删除操作旋转可能旋转到根节点,树最大高度为 `1.44log(N+2)-1.328`。 67 | 68 | 由于 `AVL Tree` 树理论上高度较低,所以查询速度稍快,但是删除操作因为旋转可能过多,会慢一点,但经过我们的优化,比如使用了非递归,只更新需要更新的树节点高度等,它们的速度是差不多的。 69 | 70 | `Java/C#/C++` 标准库内部实现都是用 `Red-Black Tree` 实现的,`Windows` 对进程地址空间的管理则使用了 `AVL Tree`。 71 | 72 | ## 例子 73 | 74 | 下面是一个基本的例子: 75 | 76 | ```go 77 | package main 78 | 79 | import ( 80 | "fmt" 81 | "github.com/hunterhug/gomap" 82 | "math/rand" 83 | "strconv" 84 | "time" 85 | ) 86 | 87 | // loop times 88 | // 循环的次数,用于随机添加和删除键值对 89 | // 可以修改成1000 90 | var num = 20 91 | 92 | func init() { 93 | // random seed 94 | // 随机数种子初始化 95 | rand.Seed(time.Now().Unix()) 96 | } 97 | 98 | // diy comparator 99 | // 内部是按键字符串来做查找树,我们把他变成整形 100 | func comparatorInt(key1, key2 string) int64 { 101 | k1, _ := strconv.Atoi(key1) 102 | k2, _ := strconv.Atoi(key2) 103 | if k1 == k2 { 104 | return 0 105 | } else if k1 > k2 { 106 | return 1 107 | } else { 108 | return -1 109 | } 110 | } 111 | 112 | func main() { 113 | checkMap := make(map[string]struct{}) 114 | 115 | // 1. new a map default is rb tree 116 | // 1. 新建一个 Map,默认为标准红黑树实现 117 | m := gomap.New() 118 | //m = gomap.NewAVLMap() // avl tree better version 119 | //m = gomap.NewAVLRecursionMap() // avl tree bad version 120 | 121 | m.SetComparator(comparatorInt) // set inner comparator 122 | 123 | for i := 0; i < num; i++ { 124 | key := fmt.Sprintf("%d", rand.Int63n(int64(num))) 125 | fmt.Println("add key:", key) 126 | checkMap[key] = struct{}{} 127 | 128 | // 2. put key pairs 129 | // 2. 放键值对 130 | m.Put(key, key) 131 | } 132 | 133 | fmt.Println("map len is ", m.Len()) 134 | 135 | // 3. can iterator 136 | // 3. 迭代器使用 137 | iterator := m.Iterator() 138 | for iterator.HasNext() { 139 | k, v := iterator.Next() 140 | fmt.Printf("Iterator key:%s,value %v\n", k, v) 141 | } 142 | 143 | // 4. get key 144 | // 4. 获取键中的值 145 | key := "9" 146 | value, exist := m.Get(key) 147 | if exist { 148 | fmt.Printf("%s exist, value is:%s\n", key, value) 149 | } else { 150 | fmt.Printf("%s not exist\n", key) 151 | } 152 | 153 | // 5. get int will err 154 | // 5. 获取键中的值,并且指定类型,因为类型是字符串,所以转成整形会报错 155 | _, _, err := m.GetInt(key) 156 | if err != nil { 157 | fmt.Println(err.Error()) 158 | } 159 | 160 | // 6. check is a rb tree 161 | // 6. 内部辅助,检查是不是一颗正常的红黑树 162 | if m.Check() { 163 | fmt.Println("is a rb tree,len:", m.Len()) 164 | } 165 | 166 | // 7. delete '9' then find '9' 167 | // 7. 删除键 '9' 然后再找 '9' 168 | m.Delete(key) 169 | value, exist = m.Get(key) 170 | if exist { 171 | fmt.Printf("%s exist, value is:%s\n", key, value) 172 | } else { 173 | fmt.Printf("%s not exist\n", key) 174 | } 175 | 176 | // 8. key list 177 | // 8. 获取键列表 178 | fmt.Printf("keyList:%#v,len:%d\n", m.KeyList(), m.Len()) 179 | fmt.Printf("keySortList:%#v,len:%d\n", m.KeySortedList(), m.Len()) 180 | 181 | // 9. delete many 182 | // 9. 删除很多键值对 183 | for key := range checkMap { 184 | v, ok := m.Get(key) 185 | fmt.Printf("find %s:%v=%v, delete key:%s\n", key, v, ok, key) 186 | m.Delete(key) 187 | if !m.Check() { 188 | fmt.Println("is not a rb tree,len:", m.Len()) 189 | } 190 | } 191 | 192 | // 10. key list 193 | // 10. 获取键列表 194 | fmt.Printf("keyList:%#v,len:%d\n", m.KeyList(), m.Len()) 195 | fmt.Printf("keySortList:%#v,len:%d\n", m.KeySortedList(), m.Len()) 196 | 197 | // 11. check is a rb tree 198 | // 11. 再次检查是否是一颗正常的红黑树 199 | if m.Check() { 200 | fmt.Println("is a rb tree,len:", m.Len()) 201 | } 202 | } 203 | ``` 204 | 205 | ## 性能测试 206 | 207 | 我进行了压测: 208 | 209 | ```go 210 | go test -run="bench_test.go" -test.bench=".*" -test.benchmem=1 -count=1    master  211 | goos: darwin 212 | goarch: amd64 213 | pkg: github.com/hunterhug/gomap 214 | BenchmarkGolangMapPut-12 1791264 621 ns/op 112 B/op 6 allocs/op 215 | BenchmarkRBTMapPut-12 1000000 1408 ns/op 104 B/op 6 allocs/op 216 | BenchmarkAVLMapPut-12 1000000 1440 ns/op 104 B/op 6 allocs/op 217 | BenchmarkAVLRecursionMapPut-12 1000000 2024 ns/op 104 B/op 6 allocs/op 218 | BenchmarkGolangMapDelete-12 3577232 303 ns/op 15 B/op 1 allocs/op 219 | BenchmarkRBTMapDelete-12 996924 1248 ns/op 15 B/op 1 allocs/op 220 | BenchmarkAVLMapDelete-12 1000000 1227 ns/op 15 B/op 1 allocs/op 221 | BenchmarkAVLRecursionMapDelete-12 667242 1866 ns/op 15 B/op 1 allocs/op 222 | BenchmarkGolangMapGet-12 15797131 72.2 ns/op 2 B/op 1 allocs/op 223 | BenchmarkRBTMapGet-12 5798295 195 ns/op 2 B/op 1 allocs/op 224 | BenchmarkAVLMapGet-12 5831353 197 ns/op 2 B/op 1 allocs/op 225 | BenchmarkAVLRecursionMapGet-12 5275490 228 ns/op 2 B/op 1 allocs/op 226 | BenchmarkGolangMapRandom-12 1256779 940 ns/op 146 B/op 8 allocs/op 227 | BenchmarkRBTMapRandom-12 965804 2652 ns/op 126 B/op 8 allocs/op 228 | BenchmarkAVLMapRandom-12 902004 2805 ns/op 126 B/op 8 allocs/op 229 | BenchmarkAVLRecursionMapRandom-12 701880 3309 ns/op 129 B/op 8 allocs/op 230 | PASS 231 | ok github.com/hunterhug/gomap 66.006s 232 | ``` 233 | 234 | 其中 `GolangMap` 是内置 `map`,使用空间换时间,其速度是最快的。`RBTMap` 是非递归版本的标准红黑树,`AVLMap` 是非递归版本的 `AVL` 树,这两个查找树速度差不多。注意⚠️:`AVLRecursionMap` 是递归版本的 `AVL` 树,主要用来教学用,容易理解,效果差不要使用。 235 | 236 | 如果对程序内存使用比较苛刻,在存储大量键值对情况下,不想浪费内存,可以使用二叉查找树实现的 `Map`。因为拉链法实现的 `golang map` 速度肯定更快,如果资源充足,直接使用官方 `map` 即可。 237 | 238 | 空间换时间,还是时间换空间,这是一个问题。 239 | 240 | # License 241 | 242 | ``` 243 | Copyright [2019-2021] [github.com/hunterhug] 244 | 245 | Licensed under the Apache License, Version 2.0 (the "License"); 246 | you may not use this file except in compliance with the License. 247 | You may obtain a copy of the License at 248 | 249 | http://www.apache.org/licenses/LICENSE-2.0 250 | 251 | Unless required by applicable law or agreed to in writing, software 252 | distributed under the License is distributed on an "AS IS" BASIS, 253 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 254 | See the License for the specific language governing permissions and 255 | limitations under the License. 256 | ``` 257 | -------------------------------------------------------------------------------- /avlbetter.go: -------------------------------------------------------------------------------- 1 | /* 2 | All right reserved:https://github.com/hunterhug/gomap at 2020 3 | Attribution-NonCommercial-NoDerivatives 4.0 International 4 | You can use it for education only but can't make profits for any companies and individuals! 5 | */ 6 | package gomap 7 | 8 | import ( 9 | "fmt" 10 | "sync" 11 | ) 12 | 13 | // Better AVL Tree 14 | type avlBetterTree struct { 15 | c comparator // tree key compare 16 | root *avlBetterTreeNode // tree root 17 | len int64 // tree key pairs num 18 | sync.Mutex // lock for concurrent safe 19 | } 20 | 21 | type avlBetterTreeNode struct { 22 | k string // key 23 | v interface{} // value 24 | left *avlBetterTreeNode 25 | right *avlBetterTreeNode 26 | balanceFactor int64 // balance Factor 27 | parent *avlBetterTreeNode 28 | } 29 | 30 | // cal height 31 | func (node *avlBetterTreeNode) height() int64 { 32 | if node == nil { 33 | return 0 34 | } 35 | 36 | lh := node.left.height() 37 | rh := node.right.height() 38 | if lh > rh { 39 | return lh + 1 40 | } else { 41 | return rh + 1 42 | } 43 | } 44 | 45 | func (tree *avlBetterTree) Height() int64 { 46 | return tree.root.height() 47 | } 48 | 49 | func (tree *avlBetterTree) rotateLeft(h *avlBetterTreeNode) *avlBetterTreeNode { 50 | if h != nil { 51 | x := h.right 52 | h.right = x.left 53 | 54 | if x.left != nil { 55 | x.left.parent = h 56 | } 57 | 58 | x.parent = h.parent 59 | if h.parent == nil { 60 | tree.root = x 61 | } else if h.parent.left == h { 62 | h.parent.left = x 63 | } else { 64 | h.parent.right = x 65 | } 66 | x.left = h 67 | h.parent = x 68 | 69 | // can see graph 70 | h.balanceFactor += 1 71 | if x.balanceFactor < 0 { 72 | h.balanceFactor -= x.balanceFactor 73 | } 74 | 75 | x.balanceFactor += 1 76 | if h.balanceFactor > 0 { 77 | x.balanceFactor += h.balanceFactor 78 | } 79 | 80 | return x 81 | } 82 | 83 | return nil 84 | } 85 | 86 | // 对某节点右旋转 87 | func (tree *avlBetterTree) rotateRight(h *avlBetterTreeNode) *avlBetterTreeNode { 88 | if h != nil { 89 | 90 | // 看图理解 91 | x := h.left 92 | h.left = x.right 93 | 94 | if x.right != nil { 95 | x.right.parent = h 96 | } 97 | 98 | x.parent = h.parent 99 | if h.parent == nil { 100 | tree.root = x 101 | } else if h.parent.right == h { 102 | h.parent.right = x 103 | } else { 104 | h.parent.left = x 105 | } 106 | x.right = h 107 | h.parent = x 108 | 109 | // can see graph 110 | h.balanceFactor -= 1 111 | if x.balanceFactor > 0 { 112 | h.balanceFactor -= x.balanceFactor 113 | } 114 | 115 | x.balanceFactor -= 1 116 | if h.balanceFactor < 0 { 117 | x.balanceFactor += h.balanceFactor 118 | } 119 | 120 | return x 121 | } 122 | 123 | return nil 124 | } 125 | 126 | func (tree *avlBetterTree) Put(key string, value interface{}) { 127 | tree.Lock() 128 | defer tree.Unlock() 129 | 130 | if tree.root == nil { 131 | // 根节点都是黑色 132 | tree.root = &avlBetterTreeNode{ 133 | k: key, 134 | v: value, 135 | } 136 | tree.len = 1 137 | return 138 | } 139 | 140 | var parent *avlBetterTreeNode 141 | var cmp int64 142 | node := tree.root 143 | for node != nil { 144 | cmp = tree.c(key, node.k) 145 | parent = node 146 | if cmp == 0 { 147 | node.v = value 148 | return 149 | } else if cmp < 0 { 150 | node = node.left 151 | } else { 152 | node = node.right 153 | } 154 | } 155 | 156 | newNode := &avlBetterTreeNode{ 157 | k: key, 158 | v: value, 159 | parent: parent, 160 | } 161 | 162 | if cmp < 0 { 163 | parent.left = newNode 164 | } else { 165 | parent.right = newNode 166 | } 167 | 168 | for parent != nil { 169 | // balance factor change of parent 170 | cmp = tree.c(parent.k, key) 171 | if cmp < 0 { 172 | parent.balanceFactor -= 1 173 | } else { 174 | parent.balanceFactor += 1 175 | } 176 | 177 | // parent factor can out, no need to loop 178 | if parent.balanceFactor == 0 { 179 | break 180 | } else if parent.balanceFactor < -1 { 181 | // right higher 182 | if parent.right.balanceFactor == 1 { 183 | tree.rotateRight(parent.right) 184 | } 185 | 186 | // root change inside 187 | tree.rotateLeft(parent) 188 | break 189 | } else if parent.balanceFactor > 1 { 190 | if parent.left.balanceFactor == -1 { 191 | tree.rotateLeft(parent.left) 192 | } 193 | tree.rotateRight(parent) 194 | break 195 | } 196 | 197 | parent = parent.parent 198 | } 199 | 200 | tree.len++ 201 | } 202 | 203 | func (tree *avlBetterTree) Delete(key string) { 204 | tree.Lock() 205 | defer tree.Unlock() 206 | 207 | if tree.len == 0 { 208 | return 209 | } 210 | 211 | var cmp int64 212 | node := tree.root 213 | for node != nil { 214 | cmp = tree.c(key, node.k) 215 | if cmp == 0 { 216 | break 217 | } else if cmp < 0 { 218 | node = node.left 219 | } else { 220 | node = node.right 221 | } 222 | } 223 | 224 | if node == nil { 225 | return 226 | } 227 | 228 | var maxNode, minNode *avlBetterTreeNode 229 | if node.left != nil { 230 | // find left tree max k 231 | maxNode = node.left 232 | 233 | for maxNode.left != nil || maxNode.right != nil { 234 | for maxNode.right != nil { 235 | maxNode = maxNode.right 236 | } 237 | 238 | node.k = maxNode.k 239 | node.v = maxNode.v 240 | 241 | if maxNode.left != nil { 242 | // max k has left node 243 | node = maxNode 244 | 245 | // let left node replace 246 | maxNode = maxNode.left 247 | } 248 | } 249 | 250 | node.k = maxNode.k 251 | node.v = maxNode.v 252 | node = maxNode // delete this node 253 | } 254 | 255 | if node.right != nil { 256 | minNode = node.right 257 | 258 | for minNode.left != nil || minNode.right != nil { 259 | for minNode.left != nil { 260 | minNode = minNode.left 261 | } 262 | 263 | node.k = minNode.k 264 | node.v = minNode.v 265 | 266 | if minNode.right != nil { 267 | node = minNode 268 | minNode = minNode.right 269 | } 270 | } 271 | 272 | node.k = minNode.k 273 | node.v = minNode.v 274 | node = minNode 275 | } 276 | 277 | parent := node.parent 278 | ps := node 279 | 280 | for parent != nil { 281 | if parent.left == ps { 282 | parent.balanceFactor -= 1 283 | } else { 284 | parent.balanceFactor += 1 285 | } 286 | 287 | if parent.balanceFactor < -1 { 288 | if parent.right.balanceFactor == 1 { 289 | tree.rotateRight(parent.right) 290 | } 291 | parent = tree.rotateLeft(parent) 292 | } else if parent.balanceFactor > 1 { 293 | if parent.left.balanceFactor == -1 { 294 | tree.rotateLeft(parent.left) 295 | } 296 | parent = tree.rotateRight(parent) 297 | } 298 | 299 | // if bal break 300 | if parent.balanceFactor == -1 || parent.balanceFactor == 1 { 301 | break 302 | } 303 | 304 | // may be continue to deal father 305 | ps = parent 306 | parent = parent.parent 307 | } 308 | 309 | if node.parent != nil { 310 | if node.parent.left == node { 311 | node.parent.left = nil 312 | } else { 313 | node.parent.right = nil 314 | } 315 | 316 | node.parent = nil 317 | } 318 | 319 | if node == tree.root { 320 | tree.root = nil 321 | } 322 | 323 | tree.len-- 324 | } 325 | 326 | // MinKey find min key pairs 327 | func (tree *avlBetterTree) MinKey() (key string, value interface{}, exist bool) { 328 | tree.Lock() 329 | defer tree.Unlock() 330 | if tree.root == nil { 331 | // 如果是空树,返回空 332 | return 333 | } 334 | 335 | node := tree.root.minNode() 336 | return node.k, node.v, true 337 | } 338 | 339 | func (node *avlBetterTreeNode) minNode() *avlBetterTreeNode { 340 | if node.left == nil { 341 | return node 342 | } 343 | 344 | return node.left.minNode() 345 | } 346 | 347 | // MaxKey find max key pairs 348 | func (tree *avlBetterTree) MaxKey() (key string, value interface{}, exist bool) { 349 | tree.Lock() 350 | defer tree.Unlock() 351 | if tree.root == nil { 352 | // 如果是空树,返回空 353 | return 354 | } 355 | 356 | node := tree.root.maxNode() 357 | return node.k, node.v, true 358 | } 359 | 360 | func (node *avlBetterTreeNode) maxNode() *avlBetterTreeNode { 361 | if node.right == nil { 362 | return node 363 | } 364 | 365 | return node.right.maxNode() 366 | } 367 | 368 | func (tree *avlBetterTree) Get(key string) (value interface{}, exist bool) { 369 | tree.Lock() 370 | defer tree.Unlock() 371 | 372 | if tree.root == nil { 373 | return 374 | } 375 | 376 | var cmp int64 377 | node := tree.root 378 | for { 379 | cmp = tree.c(key, node.k) 380 | if cmp == 0 { 381 | return node.v, true 382 | } else if cmp < 0 { 383 | node = node.left 384 | } else { 385 | node = node.right 386 | } 387 | 388 | if node == nil { 389 | break 390 | } 391 | } 392 | 393 | return 394 | } 395 | 396 | func (tree *avlBetterTree) Contains(key string) (exist bool) { 397 | tree.Lock() 398 | defer tree.Unlock() 399 | 400 | if tree.root == nil { 401 | return 402 | } 403 | 404 | var cmp int64 405 | node := tree.root 406 | for { 407 | cmp = tree.c(key, node.k) 408 | if cmp == 0 { 409 | return true 410 | } else if cmp < 0 { 411 | node = node.left 412 | } else { 413 | node = node.right 414 | } 415 | 416 | if node == nil { 417 | break 418 | } 419 | } 420 | 421 | return 422 | } 423 | 424 | func (tree *avlBetterTree) Len() int64 { 425 | return tree.len 426 | } 427 | 428 | func (tree *avlBetterTree) GetInt(key string) (value int, exist bool, err error) { 429 | var v interface{} 430 | v, exist = tree.Get(key) 431 | if !exist { 432 | return 433 | } 434 | 435 | value, ok := v.(int) 436 | if !ok { 437 | err = ReflectError(v) 438 | return 439 | } 440 | 441 | return value, true, nil 442 | } 443 | 444 | func (tree *avlBetterTree) GetInt64(key string) (value int64, exist bool, err error) { 445 | var v interface{} 446 | v, exist = tree.Get(key) 447 | if !exist { 448 | return 449 | } 450 | 451 | value, ok := v.(int64) 452 | if !ok { 453 | err = ReflectError(v) 454 | return 455 | } 456 | 457 | return value, true, nil 458 | } 459 | 460 | func (tree *avlBetterTree) GetString(key string) (value string, exist bool, err error) { 461 | var v interface{} 462 | v, exist = tree.Get(key) 463 | if !exist { 464 | return 465 | } 466 | 467 | value, ok := v.(string) 468 | if !ok { 469 | err = ReflectError(v) 470 | return 471 | } 472 | 473 | return value, true, nil 474 | } 475 | 476 | func (tree *avlBetterTree) GetFloat64(key string) (value float64, exist bool, err error) { 477 | var v interface{} 478 | v, exist = tree.Get(key) 479 | if !exist { 480 | return 481 | } 482 | 483 | value, ok := v.(float64) 484 | if !ok { 485 | err = ReflectError(v) 486 | return 487 | } 488 | 489 | return value, true, nil 490 | } 491 | 492 | func (tree *avlBetterTree) GetBytes(key string) (value []byte, exist bool, err error) { 493 | var v interface{} 494 | v, exist = tree.Get(key) 495 | if !exist { 496 | return 497 | } 498 | 499 | value, ok := v.([]byte) 500 | if !ok { 501 | err = ReflectError(v) 502 | return 503 | } 504 | 505 | return value, true, nil 506 | } 507 | 508 | func (tree *avlBetterTree) KeySortedList() []string { 509 | tree.Lock() 510 | defer tree.Unlock() 511 | keyList := make([]string, 0, tree.len) 512 | return tree.root.midOrder(keyList) 513 | } 514 | 515 | func (node *avlBetterTreeNode) midOrder(keyList []string) []string { 516 | if node == nil { 517 | return keyList 518 | } 519 | 520 | keyList = node.left.midOrder(keyList) 521 | keyList = append(keyList, node.k) 522 | keyList = node.right.midOrder(keyList) 523 | 524 | return keyList 525 | } 526 | 527 | func (tree *avlBetterTree) Check() bool { 528 | if tree == nil || tree.root == nil { 529 | return true 530 | } 531 | 532 | if tree.root.isAVL(tree.c) { 533 | return true 534 | } 535 | 536 | return false 537 | } 538 | 539 | // 判断节点是否符合 AVL 树的定义 540 | func (node *avlBetterTreeNode) isAVL(compare comparator) bool { 541 | if node == nil { 542 | return true 543 | } 544 | 545 | if node.balanceFactor != node.left.height()-node.right.height() { 546 | fmt.Printf("balanceFactor %d != %d-%d\n", node.balanceFactor, node.left.height(), node.right.height()) 547 | fmt.Printf("balanceFactor %#v != \n%#v-\n%#v\n", node, node.left, node.right) 548 | return false 549 | } 550 | // 左右子树都为空,那么是叶子节点 551 | if node.left == nil && node.right == nil { 552 | // 叶子节点高度应该为1 553 | if node.height() == 1 { 554 | return true 555 | } else { 556 | fmt.Println("leaf node height must is 1, now is:", node.height()) 557 | return false 558 | } 559 | } else if node.left != nil && node.right != nil { 560 | // 左右子树都是满的 561 | // 左儿子必须比父亲小,右儿子必须比父亲大 562 | cmp1 := compare(node.left.k, node.k) 563 | cmp2 := compare(node.right.k, node.k) 564 | if cmp1 < 0 && cmp2 > 0 { 565 | } else { 566 | // 不符合 AVL 树定义 567 | fmt.Printf("father is %v lchild is %v, rchild is %v\n", node.k, node.left.k, node.right.k) 568 | return false 569 | } 570 | 571 | bal := node.left.height() - node.right.height() 572 | if bal < 0 { 573 | bal = -bal 574 | } 575 | 576 | // 子树高度差不能大于1 577 | if bal > 1 { 578 | fmt.Println("sub tree height bal is ", bal) 579 | return false 580 | } 581 | 582 | // 如果左子树比右子树高,那么父亲的高度等于左子树+1 583 | if node.left.height() > node.right.height() { 584 | if node.height() == node.left.height()+1 { 585 | } else { 586 | fmt.Printf("%#v height:%v,left sub tree height: %v,right sub tree height:%v\n", node, node.height(), node.left.height(), node.right.height()) 587 | return false 588 | } 589 | } else { 590 | // 如果右子树比左子树高,那么父亲的高度等于右子树+1 591 | if node.height() == node.right.height()+1 { 592 | } else { 593 | fmt.Printf("%#v height:%v,left sub tree height: %v,right sub tree height:%v\n", node, node.height(), node.left.height(), node.right.height()) 594 | return false 595 | } 596 | } 597 | 598 | // 递归判断子树 599 | if !node.left.isAVL(compare) { 600 | return false 601 | } 602 | 603 | // 递归判断子树 604 | if !node.right.isAVL(compare) { 605 | return false 606 | } 607 | 608 | } else { 609 | // 只存在一棵子树 610 | if node.right != nil { 611 | // 子树高度只能是1 612 | if node.right.height() == 1 && node.right.left == nil && node.right.right == nil { 613 | cmp := compare(node.right.k, node.k) 614 | if cmp > 0 { 615 | // 右节点必须比父亲大 616 | } else { 617 | fmt.Printf("%v has only right tree,but right small:%v", node.k, node.right.k) 618 | return false 619 | } 620 | } else { 621 | fmt.Printf("%v has only right tree height:%d,but right has lc: %#v, rc:%#v", node.k, node.right.height(), node.right.left, node.right.right) 622 | return false 623 | } 624 | } else { 625 | if node.left.height() == 1 && node.left.left == nil && node.left.right == nil { 626 | cmp := compare(node.left.k, node.k) 627 | if cmp < 0 { 628 | // 左节点必须比父亲小 629 | } else { 630 | fmt.Printf("%v has only left tree,but left small:%v", node.k, node.left.k) 631 | return false 632 | } 633 | } else { 634 | fmt.Printf("%v has only left tree height:%d,but left has lc: %#v, rc:%#v", node.k, node.left.height(), node.left.left, node.left.right) 635 | return false 636 | } 637 | } 638 | } 639 | 640 | return true 641 | } 642 | 643 | func (node *avlBetterTreeNode) leftOf() bsTreeNode { 644 | if node.left == nil { 645 | return nil 646 | } 647 | 648 | return node.left 649 | } 650 | 651 | func (node *avlBetterTreeNode) rightOf() bsTreeNode { 652 | if node.right == nil { 653 | return nil 654 | } 655 | 656 | return node.right 657 | } 658 | 659 | // not check node nil, may be panic, user should deal by oneself 660 | func (node *avlBetterTreeNode) values() (key string, value interface{}) { 661 | return node.k, node.v 662 | } 663 | 664 | func (tree *avlBetterTree) KeyList() []string { 665 | tree.Lock() 666 | defer tree.Unlock() 667 | 668 | if tree.root == nil { 669 | return []string{} 670 | } 671 | 672 | keyList := make([]string, 0, tree.len) 673 | iterator := tree.Iterator() 674 | for iterator.HasNext() { 675 | k, _ := iterator.Next() 676 | keyList = append(keyList, k) 677 | } 678 | 679 | return keyList 680 | 681 | } 682 | 683 | func (tree *avlBetterTree) Iterator() MapIterator { 684 | q := new(linkQueue) 685 | if tree.root != nil { 686 | q.add(tree.root) 687 | } 688 | return q 689 | } 690 | 691 | func (tree *avlBetterTree) SetComparator(c comparator) Map { 692 | tree.Lock() 693 | defer tree.Unlock() 694 | if tree.len == 0 { 695 | tree.c = c 696 | } 697 | 698 | return tree 699 | } 700 | -------------------------------------------------------------------------------- /avltree.go: -------------------------------------------------------------------------------- 1 | /* 2 | All right reserved:https://github.com/hunterhug/gomap at 2020 3 | Attribution-NonCommercial-NoDerivatives 4.0 International 4 | You can use it for education only but can't make profits for any companies and individuals! 5 | */ 6 | package gomap 7 | 8 | import ( 9 | "fmt" 10 | "sync" 11 | ) 12 | 13 | // Deprecated 14 | // AVL Tree 15 | // Use recursion. 16 | type avlTree struct { 17 | c comparator // tree key compare 18 | root *avlTreeNode // tree root node 19 | len int64 // tree key pairs num 20 | sync.Mutex // lock for concurrent safe 21 | } 22 | 23 | // Deprecated 24 | // AVL节点 25 | type avlTreeNode struct { 26 | k string // key 27 | v interface{} // value 28 | height int64 // 该节点作为树根节点,树的高度,方便计算平衡因子 29 | left *avlTreeNode // 左子树 30 | right *avlTreeNode // 右字树 31 | } 32 | 33 | func (node *avlTreeNode) h() int64 { 34 | if node == nil { 35 | return 0 36 | } 37 | 38 | lh := node.left.h() 39 | rh := node.right.h() 40 | if lh > rh { 41 | return lh + 1 42 | } else { 43 | return rh + 1 44 | } 45 | } 46 | 47 | func (tree *avlTree) Height() int64 { 48 | return tree.root.h() 49 | } 50 | 51 | // 更新节点的树高度 52 | func (node *avlTreeNode) updateHeight() { 53 | if node == nil { 54 | return 55 | } 56 | 57 | var leftHeight, rightHeight int64 = 0, 0 58 | if node.left != nil { 59 | leftHeight = node.left.height 60 | } 61 | if node.right != nil { 62 | rightHeight = node.right.height 63 | } 64 | 65 | //leftHeight, rightHeight := height(node.left), height(node.right) 66 | 67 | // 哪个子树高算哪棵的 68 | maxHeight := leftHeight 69 | if rightHeight > maxHeight { 70 | maxHeight = rightHeight 71 | } 72 | // 高度加上自己那一层 73 | node.height = maxHeight + 1 74 | } 75 | 76 | // 计算平衡因子 77 | func (node *avlTreeNode) balanceFactor() int64 { 78 | //return height(node.left) - height(node.right) 79 | var leftHeight, rightHeight int64 = 0, 0 80 | if node.left != nil { 81 | leftHeight = node.left.height 82 | } 83 | if node.right != nil { 84 | rightHeight = node.right.height 85 | } 86 | return leftHeight - rightHeight 87 | } 88 | 89 | // 单右旋操作,看图说话 90 | func (_ *avlTreeNode) rightRotation(Root *avlTreeNode) *avlTreeNode { 91 | defer func() { 92 | if err := recover(); err != nil { 93 | fmt.Printf("%#v\n,l:%#v\n,r:%#v\n", Root, Root.left, Root.right) 94 | panic(err) 95 | } 96 | }() 97 | // 只有Pivot和B,Root位置变了 98 | Pivot := Root.left 99 | B := Pivot.right 100 | Pivot.right = Root 101 | Root.left = B 102 | 103 | // 只有Root和Pivot变化了高度 104 | Root.updateHeight() 105 | Pivot.updateHeight() 106 | return Pivot 107 | } 108 | 109 | // 单左旋操作,看图说话 110 | func (_ *avlTreeNode) leftRotation(Root *avlTreeNode) *avlTreeNode { 111 | defer func() { 112 | if err := recover(); err != nil { 113 | fmt.Printf("%#v\n,l:%#v\n,r:%#v\n", Root, Root.left, Root.right) 114 | panic(err) 115 | } 116 | }() 117 | // 只有Pivot和B,Root位置变了 118 | Pivot := Root.right 119 | B := Pivot.left 120 | Pivot.left = Root 121 | Root.right = B 122 | 123 | // 只有Root和Pivot变化了高度 124 | Root.updateHeight() 125 | Pivot.updateHeight() 126 | return Pivot 127 | } 128 | 129 | // 先左后右旋操作,看图说话 130 | func (_ *avlTreeNode) leftRightRotation(node *avlTreeNode) *avlTreeNode { 131 | node.left = node.leftRotation(node.left) 132 | return node.rightRotation(node) 133 | } 134 | 135 | // 先右后左旋操作,看图说话 136 | func (_ *avlTreeNode) rightLeftRotation(node *avlTreeNode) *avlTreeNode { 137 | node.right = node.rightRotation(node.right) 138 | return node.leftRotation(node) 139 | } 140 | 141 | // SetComparator set Comparator 142 | // Deprecated 143 | func (tree *avlTree) SetComparator(c comparator) Map { 144 | tree.Lock() 145 | defer tree.Unlock() 146 | if tree.len == 0 { 147 | tree.c = c 148 | } 149 | return tree 150 | } 151 | 152 | // Put 添加元素 153 | // Deprecated 154 | func (tree *avlTree) Put(key string, value interface{}) { 155 | // add lock 156 | tree.Lock() 157 | defer tree.Unlock() 158 | 159 | add := false 160 | if tree.root != nil { 161 | node := tree.root.find(tree.c, key) 162 | if node == nil { 163 | add = true 164 | } 165 | } else { 166 | add = true 167 | } 168 | 169 | // 往树根添加元素,会返回新的树根 170 | tree.root = tree.root.put(tree.c, key, value) 171 | 172 | if add { 173 | tree.len = tree.len + 1 174 | } 175 | } 176 | 177 | func (node *avlTreeNode) put(compare comparator, key string, value interface{}) *avlTreeNode { 178 | // 添加值到根节点node,如果node为空,那么让值成为新的根节点,树的高度为1 179 | if node == nil { 180 | return &avlTreeNode{k: key, v: value, height: 1} 181 | } 182 | 183 | // 如果值重复,什么都不用做,直接更新次数 184 | if node.k == key { 185 | node.v = value 186 | return node 187 | } 188 | 189 | // 辅助变量 190 | var newTreeNode *avlTreeNode 191 | 192 | cmp := compare(key, node.k) 193 | if cmp > 0 { 194 | // 插入的值大于节点值,要从右子树继续插入 195 | node.right = node.right.put(compare, key, value) 196 | // 平衡因子,插入右子树后,要确保树根左子树的高度不能比右子树低一层。 197 | factor := node.balanceFactor() 198 | // 右子树的高度变高了,导致左子树-右子树的高度从-1变成了-2。 199 | if factor == -2 { 200 | cmp1 := compare(key, node.right.k) 201 | if cmp1 > 0 { 202 | // 表示在右子树上插上右儿子导致失衡,需要单左旋: 203 | newTreeNode = node.leftRotation(node) 204 | } else { 205 | //表示在右子树上插上左儿子导致失衡,先右后左旋: 206 | newTreeNode = node.rightLeftRotation(node) 207 | } 208 | } 209 | } else { 210 | // 插入的值小于节点值,要从左子树继续插入 211 | node.left = node.left.put(compare, key, value) 212 | // 平衡因子,插入左子树后,要确保树根左子树的高度不能比右子树高一层。 213 | factor := node.balanceFactor() 214 | // 左子树的高度变高了,导致左子树-右子树的高度从1变成了2。 215 | if factor == 2 { 216 | cmp1 := compare(key, node.left.k) 217 | if cmp1 < 0 { 218 | // 表示在左子树上插上左儿子导致失衡,需要单右旋: 219 | newTreeNode = node.rightRotation(node) 220 | } else { 221 | //表示在左子树上插上右儿子导致失衡,先左后右旋: 222 | newTreeNode = node.leftRightRotation(node) 223 | } 224 | } 225 | } 226 | 227 | if newTreeNode == nil { 228 | // 表示什么旋转都没有,根节点没变,直接刷新树高度 229 | node.updateHeight() 230 | return node 231 | } else { 232 | // 旋转了,树根节点变了,需要刷新新的树根高度 233 | newTreeNode.updateHeight() 234 | return newTreeNode 235 | } 236 | } 237 | 238 | // MinKey find min key pairs 239 | // Deprecated 240 | func (tree *avlTree) MinKey() (key string, value interface{}, exist bool) { 241 | // add lock 242 | tree.Lock() 243 | defer tree.Unlock() 244 | if tree.root == nil { 245 | // 如果是空树,返回空 246 | return 247 | } 248 | 249 | node := tree.root.minNode() 250 | return node.k, node.v, true 251 | } 252 | 253 | func (node *avlTreeNode) minNode() *avlTreeNode { 254 | // 左子树为空,表面已经是最左的节点了,该值就是最小值 255 | if node.left == nil { 256 | return node 257 | } 258 | 259 | // 一直左子树递归 260 | return node.left.minNode() 261 | } 262 | 263 | // MaxKey 找出最大值的节点 264 | // Deprecated 265 | func (tree *avlTree) MaxKey() (key string, value interface{}, exist bool) { 266 | // add lock 267 | tree.Lock() 268 | defer tree.Unlock() 269 | if tree.root == nil { 270 | // 如果是空树,返回空 271 | return 272 | } 273 | node := tree.root.maxNode() 274 | return node.k, node.v, true 275 | } 276 | 277 | func (node *avlTreeNode) maxNode() *avlTreeNode { 278 | // 右子树为空,表面已经是最右的节点了,该值就是最大值 279 | if node.right == nil { 280 | return node 281 | } 282 | 283 | // 一直右子树递归 284 | return node.right.maxNode() 285 | } 286 | 287 | // Get 查找指定节点 288 | // Deprecated 289 | func (tree *avlTree) Get(key string) (value interface{}, exist bool) { 290 | // add lock 291 | tree.Lock() 292 | defer tree.Unlock() 293 | if tree.root == nil { 294 | // 如果是空树,返回空 295 | return 296 | } 297 | 298 | node := tree.root.find(tree.c, key) 299 | if node == nil { 300 | return nil, false 301 | } 302 | return node.v, true 303 | } 304 | 305 | func (node *avlTreeNode) find(compare comparator, key string) *avlTreeNode { 306 | cmp := compare(key, node.k) 307 | if cmp == 0 { 308 | // 如果该节点刚刚等于该值,那么返回该节点 309 | return node 310 | } else if cmp < 0 { 311 | // 如果查找的值小于节点值,从节点的左子树开始找 312 | if node.left == nil { 313 | // 左子树为空,表示找不到该值了,返回nil 314 | return nil 315 | } 316 | return node.left.find(compare, key) 317 | } else { 318 | // 如果查找的值大于节点值,从节点的右子树开始找 319 | if node.right == nil { 320 | // 右子树为空,表示找不到该值了,返回nil 321 | return nil 322 | } 323 | return node.right.find(compare, key) 324 | } 325 | } 326 | 327 | // Delete 删除指定的元素 328 | // Deprecated 329 | func (tree *avlTree) Delete(key string) { 330 | // add lock 331 | tree.Lock() 332 | defer tree.Unlock() 333 | if tree.len == 0 { 334 | return 335 | } 336 | 337 | // 查找元素是否存在,不存在则退出 338 | node := tree.root.find(tree.c, key) 339 | if node == nil { 340 | return 341 | } 342 | 343 | tree.root = tree.root.delete(tree.c, key) 344 | tree.len = tree.len - 1 345 | 346 | } 347 | 348 | func (node *avlTreeNode) delete(compare comparator, key string) *avlTreeNode { 349 | if node == nil { 350 | // 如果是空树,直接返回 351 | return nil 352 | } 353 | 354 | cmp := compare(key, node.k) 355 | if cmp < 0 { 356 | // 从左子树开始删除 357 | node.left = node.left.delete(compare, key) 358 | // 删除后要更新该子树高度 359 | node.left.updateHeight() 360 | } else if cmp > 0 { 361 | // 从右子树开始删除 362 | node.right = node.right.delete(compare, key) 363 | // 删除后要更新该子树高度 364 | node.right.updateHeight() 365 | } else { 366 | // 找到该值对应的节点 367 | // 该节点没有左右子树 368 | // 第一种情况,删除的节点没有儿子,直接删除即可。 369 | if node.left == nil && node.right == nil { 370 | return nil // 直接返回nil,表示直接该值删除 371 | } 372 | 373 | // 该节点有两棵子树,选择更高的哪个来替换 374 | // 第二种情况,删除的节点下有两个子树,选择高度更高的子树下的节点来替换被删除的节点,如果左子树更高,选择左子树中最大的节点,也就是左子树最右边的叶子节点,如果右子树更高,选择右子树中最小的节点,也就是右子树最左边的叶子节点。最后,删除这个叶子节点。 375 | if node.left != nil && node.right != nil { 376 | // 左子树更高,拿左子树中最大值的节点替换 377 | if node.left.height > node.right.height { 378 | maxNode := node.left 379 | for maxNode.right != nil { 380 | maxNode = maxNode.right 381 | } 382 | 383 | // 最大值的节点替换被删除节点 384 | node.k = maxNode.k 385 | node.v = maxNode.v 386 | 387 | // 把最大的节点删掉 388 | node.left = node.left.delete(compare, maxNode.k) 389 | // 删除后要更新该子树高度 390 | node.left.updateHeight() 391 | } else { 392 | // 右子树更高,拿右子树中最小值的节点替换 393 | minNode := node.right 394 | for minNode.left != nil { 395 | minNode = minNode.left 396 | } 397 | 398 | // 最小值的节点替换被删除节点 399 | node.k = minNode.k 400 | node.v = minNode.v 401 | 402 | // 把最小的节点删掉 403 | node.right = node.right.delete(compare, minNode.k) 404 | // 删除后要更新该子树高度 405 | node.right.updateHeight() 406 | } 407 | } else { 408 | // 只有左子树或只有右子树 409 | // 只有一个子树,该子树也只是一个节点,将该节点替换被删除的节点,然后置子树为空 410 | if node.left != nil { 411 | //第三种情况,删除的节点只有左子树,因为树的特征,可以知道左子树其实就只有一个节点,它本身,否则高度差就等于2了。 412 | node.k = node.left.k 413 | node.v = node.left.v 414 | node.height = 1 415 | node.left = nil 416 | } else if node.right != nil { 417 | //第四种情况,删除的节点只有右子树,因为树的特征,可以知道右子树其实就只有一个节点,它本身,否则高度差就等于2了。 418 | node.k = node.right.k 419 | node.v = node.right.v 420 | node.height = 1 421 | node.right = nil 422 | } 423 | } 424 | 425 | // 找到值后,进行替换删除后,直接返回该节点 426 | return node 427 | } 428 | 429 | // 左右子树递归删除节点后需要平衡 430 | var newNode *avlTreeNode 431 | // 相当删除了右子树的节点,左边比右边高了,不平衡 432 | if cmp > 0 && node.balanceFactor() == 2 { 433 | //fmt.Println("l-r=2 and l:", node.left.balanceFactor()) 434 | if node.left.balanceFactor() >= 0 { // why >0 will err must be checking 435 | newNode = node.rightRotation(node) 436 | } else { 437 | newNode = node.leftRightRotation(node) 438 | } 439 | // 相当删除了左子树的节点,右边比左边高了,不平衡 440 | } else if cmp < 0 && node.balanceFactor() == -2 { 441 | //fmt.Println("l-r=-2 and l:", node.right.balanceFactor()) 442 | if node.right.balanceFactor() <= 0 { 443 | newNode = node.leftRotation(node) 444 | } else { 445 | newNode = node.rightLeftRotation(node) 446 | } 447 | } 448 | 449 | if newNode == nil { 450 | node.updateHeight() 451 | return node 452 | } else { 453 | newNode.updateHeight() 454 | return newNode 455 | } 456 | } 457 | 458 | // Contains 查找指定节点 459 | // Deprecated 460 | func (tree *avlTree) Contains(key string) (exist bool) { 461 | // add lock 462 | tree.Lock() 463 | defer tree.Unlock() 464 | if tree.root == nil { 465 | // 如果是空树,返回空 466 | return 467 | } 468 | node := tree.root.find(tree.c, key) 469 | if node == nil { 470 | return false 471 | } 472 | return true 473 | } 474 | 475 | func (tree *avlTree) Len() int64 { 476 | return tree.len 477 | } 478 | 479 | func (tree *avlTree) GetInt(key string) (value int, exist bool, err error) { 480 | var v interface{} 481 | v, exist = tree.Get(key) 482 | if !exist { 483 | return 484 | } 485 | 486 | value, ok := v.(int) 487 | if !ok { 488 | err = ReflectError(v) 489 | return 490 | } 491 | 492 | return value, true, nil 493 | } 494 | 495 | func (tree *avlTree) GetInt64(key string) (value int64, exist bool, err error) { 496 | var v interface{} 497 | v, exist = tree.Get(key) 498 | if !exist { 499 | return 500 | } 501 | 502 | value, ok := v.(int64) 503 | if !ok { 504 | err = ReflectError(v) 505 | return 506 | } 507 | 508 | return value, true, nil 509 | } 510 | 511 | func (tree *avlTree) GetString(key string) (value string, exist bool, err error) { 512 | var v interface{} 513 | v, exist = tree.Get(key) 514 | if !exist { 515 | return 516 | } 517 | 518 | value, ok := v.(string) 519 | if !ok { 520 | err = ReflectError(v) 521 | return 522 | } 523 | 524 | return value, true, nil 525 | } 526 | 527 | func (tree *avlTree) GetFloat64(key string) (value float64, exist bool, err error) { 528 | var v interface{} 529 | v, exist = tree.Get(key) 530 | if !exist { 531 | return 532 | } 533 | 534 | value, ok := v.(float64) 535 | if !ok { 536 | err = ReflectError(v) 537 | return 538 | } 539 | 540 | return value, true, nil 541 | } 542 | 543 | func (tree *avlTree) GetBytes(key string) (value []byte, exist bool, err error) { 544 | var v interface{} 545 | v, exist = tree.Get(key) 546 | if !exist { 547 | return 548 | } 549 | 550 | value, ok := v.([]byte) 551 | if !ok { 552 | err = ReflectError(v) 553 | return 554 | } 555 | 556 | return value, true, nil 557 | } 558 | 559 | // KeySortedList 中序遍历 560 | // mid order get key list 561 | // Deprecated 562 | func (tree *avlTree) KeySortedList() []string { 563 | // add lock 564 | tree.Lock() 565 | defer tree.Unlock() 566 | keyList := make([]string, 0, tree.len) 567 | return tree.root.midOrder(keyList) 568 | } 569 | 570 | func (node *avlTreeNode) midOrder(keyList []string) []string { 571 | if node == nil { 572 | return keyList 573 | } 574 | 575 | // 先打印左子树 576 | keyList = node.left.midOrder(keyList) 577 | 578 | keyList = append(keyList, node.k) 579 | 580 | // 打印右子树 581 | keyList = node.right.midOrder(keyList) 582 | 583 | return keyList 584 | } 585 | 586 | // Check 验证是不是棵AVL树 587 | // Deprecated 588 | func (tree *avlTree) Check() bool { 589 | if tree == nil || tree.root == nil { 590 | return true 591 | } 592 | 593 | // 判断节点是否符合 AVL 树的定义 594 | if tree.root.isAVL(tree.c) { 595 | return true 596 | } 597 | 598 | return false 599 | } 600 | 601 | // 判断节点是否符合 AVL 树的定义 602 | func (node *avlTreeNode) isAVL(compare comparator) bool { 603 | if node == nil { 604 | return true 605 | } 606 | 607 | // 左右子树都为空,那么是叶子节点 608 | if node.left == nil && node.right == nil { 609 | // 叶子节点高度应该为1 610 | if node.height == 1 { 611 | return true 612 | } else { 613 | fmt.Println("leaf node height must is 1, now is:", node.height) 614 | return false 615 | } 616 | } else if node.left != nil && node.right != nil { 617 | // 左右子树都是满的 618 | // 左儿子必须比父亲小,右儿子必须比父亲大 619 | cmp1 := compare(node.left.k, node.k) 620 | cmp2 := compare(node.right.k, node.k) 621 | if cmp1 < 0 && cmp2 > 0 { 622 | } else { 623 | // 不符合 AVL 树定义 624 | fmt.Printf("father is %v lchild is %v, rchild is %v\n", node.k, node.left.k, node.right.k) 625 | return false 626 | } 627 | 628 | bal := node.left.height - node.right.height 629 | if bal < 0 { 630 | bal = -bal 631 | } 632 | 633 | // 子树高度差不能大于1 634 | if bal > 1 { 635 | fmt.Println("sub tree height bal is ", bal) 636 | return false 637 | } 638 | 639 | // 如果左子树比右子树高,那么父亲的高度等于左子树+1 640 | if node.left.height > node.right.height { 641 | if node.height == node.left.height+1 { 642 | } else { 643 | fmt.Printf("%#v height:%v,left sub tree height: %v,right sub tree height:%v\n", node, node.height, node.left.height, node.right.height) 644 | return false 645 | } 646 | } else { 647 | // 如果右子树比左子树高,那么父亲的高度等于右子树+1 648 | if node.height == node.right.height+1 { 649 | } else { 650 | fmt.Printf("%#v height:%v,left sub tree height: %v,right sub tree height:%v\n", node, node.height, node.left.height, node.right.height) 651 | return false 652 | } 653 | } 654 | 655 | // 递归判断子树 656 | if !node.left.isAVL(compare) { 657 | return false 658 | } 659 | 660 | // 递归判断子树 661 | if !node.right.isAVL(compare) { 662 | return false 663 | } 664 | 665 | } else { 666 | // 只存在一棵子树 667 | if node.right != nil { 668 | // 子树高度只能是1 669 | if node.right.height == 1 && node.right.left == nil && node.right.right == nil { 670 | cmp := compare(node.right.k, node.k) 671 | if cmp > 0 { 672 | // 右节点必须比父亲大 673 | } else { 674 | fmt.Printf("%v has only right tree,but right small", node.k) 675 | return false 676 | } 677 | } else { 678 | fmt.Printf("%v has only right tree height:%d,but right has lc: %#v, rc:%#v", node.k, node.right.height, node.right.left, node.right.right) 679 | return false 680 | } 681 | } else { 682 | if node.left.height == 1 && node.left.left == nil && node.left.right == nil { 683 | cmp := compare(node.left.k, node.k) 684 | if cmp < 0 { 685 | // 左节点必须比父亲小 686 | } else { 687 | fmt.Printf("%v has only left tree,but right small", node.k) 688 | return false 689 | } 690 | } else { 691 | fmt.Printf("%v has only left tree height:%d,but left has lc: %#v, rc:%#v", node.k, node.left.height, node.left.left, node.left.right) 692 | return false 693 | } 694 | } 695 | } 696 | 697 | return true 698 | } 699 | 700 | // 返回节点的左子节点 701 | func (node *avlTreeNode) leftOf() bsTreeNode { 702 | if node.left == nil { 703 | return nil 704 | } 705 | 706 | return node.left 707 | } 708 | 709 | // 返回节点的右子节点 710 | func (node *avlTreeNode) rightOf() bsTreeNode { 711 | if node.right == nil { 712 | return nil 713 | } 714 | 715 | return node.right 716 | } 717 | 718 | // not check node nil, may be panic, user should deal by oneself 719 | func (node *avlTreeNode) values() (key string, value interface{}) { 720 | return node.k, node.v 721 | } 722 | 723 | func (tree *avlTree) KeyList() []string { 724 | tree.Lock() 725 | defer tree.Unlock() 726 | 727 | if tree.root == nil { 728 | return []string{} 729 | } 730 | 731 | keyList := make([]string, 0, tree.len) 732 | iterator := tree.Iterator() 733 | for iterator.HasNext() { 734 | k, _ := iterator.Next() 735 | keyList = append(keyList, k) 736 | } 737 | 738 | return keyList 739 | 740 | } 741 | 742 | func (tree *avlTree) Iterator() MapIterator { 743 | q := new(linkQueue) 744 | if tree.root != nil { 745 | q.add(tree.root) 746 | } 747 | return q 748 | } -------------------------------------------------------------------------------- /bench_test.go: -------------------------------------------------------------------------------- 1 | package gomap 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "testing" 7 | ) 8 | 9 | var ( 10 | randNum = 987654 11 | ) 12 | 13 | // go test -run="bench_test.go" -test.bench=".*" -test.benchmem=1 -count=3 14 | // -test.benchmem : 是否在性能测试的时候输出内存情况 15 | // 循环次数, 平均每次执行时间 16 | func BenchmarkGolangMapPut(b *testing.B) { 17 | b.StopTimer() 18 | 19 | rand.Seed(int64(randNum)) 20 | 21 | m := make(map[string]interface{}, 0) 22 | b.StartTimer() 23 | for i := 0; i < b.N; i++ { 24 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 25 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 26 | m[key] = xx 27 | } 28 | } 29 | 30 | func BenchmarkRBTMapPut(b *testing.B) { 31 | b.StopTimer() 32 | 33 | rand.Seed(int64(randNum)) 34 | 35 | m := NewMap() 36 | b.StartTimer() 37 | for i := 0; i < b.N; i++ { 38 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 39 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 40 | m.Put(key, xx) 41 | } 42 | } 43 | 44 | func BenchmarkAVLMapPut(b *testing.B) { 45 | b.StopTimer() 46 | 47 | rand.Seed(int64(randNum)) 48 | 49 | m := NewAVLMap() 50 | b.StartTimer() 51 | for i := 0; i < b.N; i++ { 52 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 53 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 54 | m.Put(key, xx) 55 | } 56 | } 57 | 58 | func BenchmarkAVLRecursionMapPut(b *testing.B) { 59 | b.StopTimer() 60 | 61 | rand.Seed(int64(randNum)) 62 | 63 | m := NewAVLRecursionMap() 64 | b.StartTimer() 65 | for i := 0; i < b.N; i++ { 66 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 67 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 68 | m.Put(key, xx) 69 | } 70 | } 71 | 72 | func BenchmarkGolangMapDelete(b *testing.B) { 73 | b.StopTimer() 74 | 75 | rand.Seed(int64(randNum)) 76 | 77 | m := make(map[string]interface{}, 0) 78 | for i := 0; i < randNum; i++ { 79 | key := fmt.Sprintf("%d", i) 80 | xx := key + fmt.Sprintf("_%v", i) 81 | m[key] = xx 82 | } 83 | 84 | b.StartTimer() 85 | for i := 0; i < b.N; i++ { 86 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 87 | delete(m, key) 88 | } 89 | } 90 | 91 | func BenchmarkRBTMapDelete(b *testing.B) { 92 | b.StopTimer() 93 | 94 | rand.Seed(int64(randNum)) 95 | 96 | m := NewMap() 97 | for i := 0; i < randNum; i++ { 98 | key := fmt.Sprintf("%d", i) 99 | xx := key + fmt.Sprintf("_%v", i) 100 | m.Put(key, xx) 101 | } 102 | 103 | b.StartTimer() 104 | for i := 0; i < b.N; i++ { 105 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 106 | m.Delete(key) 107 | } 108 | } 109 | 110 | func BenchmarkAVLMapDelete(b *testing.B) { 111 | b.StopTimer() 112 | 113 | rand.Seed(int64(randNum)) 114 | 115 | m := NewAVLMap() 116 | for i := 0; i < randNum; i++ { 117 | key := fmt.Sprintf("%d", i) 118 | xx := key + fmt.Sprintf("_%v", i) 119 | m.Put(key, xx) 120 | } 121 | 122 | b.StartTimer() 123 | for i := 0; i < b.N; i++ { 124 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 125 | m.Delete(key) 126 | } 127 | } 128 | 129 | func BenchmarkAVLRecursionMapDelete(b *testing.B) { 130 | b.StopTimer() 131 | 132 | rand.Seed(int64(randNum)) 133 | 134 | m := NewAVLRecursionMap() 135 | for i := 0; i < randNum; i++ { 136 | key := fmt.Sprintf("%d", i) 137 | xx := key + fmt.Sprintf("_%v", i) 138 | m.Put(key, xx) 139 | } 140 | 141 | b.StartTimer() 142 | for i := 0; i < b.N; i++ { 143 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 144 | m.Delete(key) 145 | } 146 | } 147 | 148 | func BenchmarkGolangMapGet(b *testing.B) { 149 | b.StopTimer() 150 | 151 | rand.Seed(int64(randNum)) 152 | 153 | m := make(map[string]interface{}, 0) 154 | for i := 0; i < randNum; i++ { 155 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 156 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 157 | m[key] = xx 158 | } 159 | 160 | b.StartTimer() 161 | for i := 0; i < b.N; i++ { 162 | key := fmt.Sprintf("%d", -2) // can not fetch forever 163 | _ = m[key] 164 | } 165 | } 166 | 167 | func BenchmarkRBTMapGet(b *testing.B) { 168 | b.StopTimer() 169 | 170 | rand.Seed(int64(randNum)) 171 | 172 | m := NewMap() 173 | for i := 0; i < randNum; i++ { 174 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 175 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 176 | m.Put(key, xx) 177 | } 178 | 179 | //b.Logf("rb tree height:%d", m.Height()) 180 | b.StartTimer() 181 | for i := 0; i < b.N; i++ { 182 | key := fmt.Sprintf("%d", -2) // can not fetch forever 183 | _, _ = m.Get(key) 184 | } 185 | } 186 | 187 | func BenchmarkAVLMapGet(b *testing.B) { 188 | b.StopTimer() 189 | 190 | rand.Seed(int64(randNum)) 191 | 192 | m := NewAVLMap() 193 | for i := 0; i < randNum; i++ { 194 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 195 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 196 | m.Put(key, xx) 197 | } 198 | 199 | //b.Logf("avl tree height:%d", m.Height()) 200 | b.StartTimer() 201 | for i := 0; i < b.N; i++ { 202 | key := fmt.Sprintf("%d", -2) // can not fetch forever 203 | _, _ = m.Get(key) 204 | } 205 | } 206 | 207 | func BenchmarkAVLRecursionMapGet(b *testing.B) { 208 | b.StopTimer() 209 | 210 | rand.Seed(int64(randNum)) 211 | 212 | m := NewAVLRecursionMap() 213 | for i := 0; i < randNum; i++ { 214 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 215 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 216 | m.Put(key, xx) 217 | } 218 | 219 | //b.Logf("avl recur tree height:%d", m.Height()) 220 | b.StartTimer() 221 | for i := 0; i < b.N; i++ { 222 | key := fmt.Sprintf("%d", -2) // can not fetch forever 223 | _, _ = m.Get(key) 224 | } 225 | } 226 | 227 | func BenchmarkGolangMapRandom(b *testing.B) { 228 | b.StopTimer() 229 | 230 | rand.Seed(int64(randNum)) 231 | 232 | m := make(map[string]interface{}, 0) 233 | 234 | b.StartTimer() 235 | for i := 0; i < b.N; i++ { 236 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 237 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 238 | m[key] = xx 239 | 240 | key = fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 241 | delete(m, key) 242 | } 243 | } 244 | 245 | func BenchmarkRBTMapRandom(b *testing.B) { 246 | b.StopTimer() 247 | 248 | rand.Seed(int64(randNum)) 249 | 250 | m := NewMap() 251 | b.StartTimer() 252 | for i := 0; i < b.N; i++ { 253 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 254 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 255 | m.Put(key, xx) 256 | 257 | key = fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 258 | m.Delete(key) 259 | } 260 | } 261 | 262 | func BenchmarkAVLMapRandom(b *testing.B) { 263 | b.StopTimer() 264 | 265 | rand.Seed(int64(randNum)) 266 | 267 | m := NewAVLMap() 268 | b.StartTimer() 269 | for i := 0; i < b.N; i++ { 270 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 271 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 272 | m.Put(key, xx) 273 | 274 | key = fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 275 | m.Delete(key) 276 | } 277 | } 278 | 279 | func BenchmarkAVLRecursionMapRandom(b *testing.B) { 280 | b.StopTimer() 281 | 282 | rand.Seed(int64(randNum)) 283 | 284 | m := NewAVLRecursionMap() 285 | b.StartTimer() 286 | for i := 0; i < b.N; i++ { 287 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 288 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 289 | m.Put(key, xx) 290 | 291 | key = fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 292 | m.Delete(key) 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/hunterhug/gomap" 6 | "math/rand" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | // loop times 12 | // 循环的次数,用于随机添加和删除键值对 13 | // 可以修改成1000 14 | var num = 20 15 | 16 | func init() { 17 | // random seed 18 | // 随机数种子初始化 19 | rand.Seed(time.Now().Unix()) 20 | } 21 | 22 | // diy comparator 23 | // 内部是按键字符串来做查找树,我们把他变成整形 24 | func comparatorInt(key1, key2 string) int64 { 25 | k1, _ := strconv.Atoi(key1) 26 | k2, _ := strconv.Atoi(key2) 27 | if k1 == k2 { 28 | return 0 29 | } else if k1 > k2 { 30 | return 1 31 | } else { 32 | return -1 33 | } 34 | } 35 | 36 | func main() { 37 | checkMap := make(map[string]struct{}) 38 | 39 | // 1. new a map default is rb tree 40 | // 1. 新建一个 Map,默认为标准红黑树实现 41 | m := gomap.New() 42 | //m = gomap.NewAVLMap() // avl tree better version 43 | //m = gomap.NewAVLRecursionMap() // avl tree bad version 44 | 45 | m.SetComparator(comparatorInt) // set inner comparator 46 | 47 | for i := 0; i < num; i++ { 48 | key := fmt.Sprintf("%d", rand.Int63n(int64(num))) 49 | fmt.Println("add key:", key) 50 | checkMap[key] = struct{}{} 51 | 52 | // 2. put key pairs 53 | // 2. 放键值对 54 | m.Put(key, key) 55 | } 56 | 57 | fmt.Println("map len is ", m.Len()) 58 | 59 | // 3. can iterator 60 | // 3. 迭代器使用 61 | iterator := m.Iterator() 62 | for iterator.HasNext() { 63 | k, v := iterator.Next() 64 | fmt.Printf("Iterator key:%s,value %v\n", k, v) 65 | } 66 | 67 | // 4. get key 68 | // 4. 获取键中的值 69 | key := "9" 70 | value, exist := m.Get(key) 71 | if exist { 72 | fmt.Printf("%s exist, value is:%s\n", key, value) 73 | } else { 74 | fmt.Printf("%s not exist\n", key) 75 | } 76 | 77 | // 5. get int will err 78 | // 5. 获取键中的值,并且指定类型,因为类型是字符串,所以转成整形会报错 79 | _, _, err := m.GetInt(key) 80 | if err != nil { 81 | fmt.Println(err.Error()) 82 | } 83 | 84 | // 6. check is a rb tree 85 | // 6. 内部辅助,检查是不是一颗正常的红黑树 86 | if m.Check() { 87 | fmt.Println("is a rb tree,len:", m.Len()) 88 | } 89 | 90 | // 7. delete '9' then find '9' 91 | // 7. 删除键 '9' 然后再找 '9' 92 | m.Delete(key) 93 | value, exist = m.Get(key) 94 | if exist { 95 | fmt.Printf("%s exist, value is:%s\n", key, value) 96 | } else { 97 | fmt.Printf("%s not exist\n", key) 98 | } 99 | 100 | // 8. key list 101 | // 8. 获取键列表 102 | fmt.Printf("keyList:%#v,len:%d\n", m.KeyList(), m.Len()) 103 | fmt.Printf("keySortList:%#v,len:%d\n", m.KeySortedList(), m.Len()) 104 | 105 | // 9. delete many 106 | // 9. 删除很多键值对 107 | for key := range checkMap { 108 | v, ok := m.Get(key) 109 | fmt.Printf("find %s:%v=%v, delete key:%s\n", key, v, ok, key) 110 | m.Delete(key) 111 | if !m.Check() { 112 | fmt.Println("is not a rb tree,len:", m.Len()) 113 | } 114 | } 115 | 116 | // 10. key list 117 | // 10. 获取键列表 118 | fmt.Printf("keyList:%#v,len:%d\n", m.KeyList(), m.Len()) 119 | fmt.Printf("keySortList:%#v,len:%d\n", m.KeySortedList(), m.Len()) 120 | 121 | // 11. check is a rb tree 122 | // 11. 再次检查是否是一颗正常的红黑树 123 | if m.Check() { 124 | fmt.Println("is a rb tree,len:", m.Len()) 125 | } 126 | } -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/hunterhug/gomap 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /gomap.go: -------------------------------------------------------------------------------- 1 | /* 2 | All right reserved:https://github.com/hunterhug/gomap at 2020 3 | Attribution-NonCommercial-NoDerivatives 4.0 International 4 | You can use it for education only but can't make profits for any companies and individuals! 5 | */ 6 | package gomap // import "github.com/hunterhug/gomap" 7 | 8 | import "strings" 9 | 10 | type comparator func(key1, key2 string) int64 11 | 12 | // Map method 13 | // design to be concurrent safe 14 | // should support int key? 15 | type Map interface { 16 | Put(key string, value interface{}) // put key pairs 17 | Delete(key string) // delete a key 18 | Get(key string) (value interface{}, exist bool) // get value from key 19 | GetInt(key string) (value int, exist bool, err error) // get value auto change to Int 20 | GetInt64(key string) (value int64, exist bool, err error) // get value auto change to Int64 21 | GetString(key string) (value string, exist bool, err error) // get value auto change to string 22 | GetFloat64(key string) (value float64, exist bool, err error) // get value auto change to string 23 | GetBytes(key string) (value []byte, exist bool, err error) // get value auto change to []byte 24 | Contains(key string) (exist bool) // map contains key? 25 | Len() int64 // map key pairs num 26 | KeyList() []string // map key out to list from top to bottom which is layer order 27 | KeySortedList() []string // map key out to list sorted 28 | Iterator() MapIterator // map iterator, iterator from top to bottom which is layer order 29 | MaxKey() (key string, value interface{}, exist bool) // find max key pairs 30 | MinKey() (key string, value interface{}, exist bool) // find min key pairs 31 | SetComparator(comparator) Map // set compare func to control key compare 32 | Check() bool // just help 33 | Height() int64 // just help 34 | } 35 | 36 | // MapIterator Iterator concurrent not safe 37 | // you should deal by yourself 38 | type MapIterator interface { 39 | HasNext() bool 40 | Next() (key string, value interface{}) 41 | } 42 | 43 | // NewMap default map is rbt implement 44 | func NewMap() Map { 45 | t := new(rbTree) 46 | t.c = comparatorDefault 47 | return t 48 | } 49 | 50 | // New default map is rbt implement 51 | func New() Map { 52 | t := new(rbTree) 53 | t.c = comparatorDefault 54 | return t 55 | } 56 | 57 | // NewRBMap default map is rbt implement 58 | func NewRBMap() Map { 59 | t := new(rbTree) 60 | t.c = comparatorDefault 61 | return t 62 | } 63 | 64 | // NewAVLRecursionMap new a avl map 65 | func NewAVLRecursionMap() Map { 66 | t := new(avlTree) 67 | t.c = comparatorDefault 68 | return t 69 | } 70 | 71 | // NewAVLMap new a avl map 72 | func NewAVLMap() Map { 73 | t := new(avlBetterTree) 74 | t.c = comparatorDefault 75 | return t 76 | } 77 | 78 | // compare two key 79 | func comparatorDefault(key1, key2 string) int64 { 80 | return int64(strings.Compare(key1, key2)) 81 | } 82 | -------------------------------------------------------------------------------- /gomap_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | All right reserved:https://github.com/hunterhug/gomap at 2020 3 | Attribution-NonCommercial-NoDerivatives 4.0 International 4 | You can use it for education only but can't make profits for any companies and individuals! 5 | */ 6 | package gomap 7 | 8 | import ( 9 | "fmt" 10 | "math/rand" 11 | "testing" 12 | "time" 13 | ) 14 | 15 | func TestNew(t *testing.T) { 16 | rw := make(map[string]interface{}) 17 | 18 | // loop times 19 | var num = 10000 20 | randNum := 100000000 21 | rand.Seed(time.Now().Unix()) 22 | // 1. new a map 23 | m := New() 24 | m = NewAVLMap() 25 | for i := 0; i < num; i++ { 26 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 27 | //fmt.Println("add key:", key) 28 | // 2. put key pairs 29 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 30 | m.Put(key, xx) 31 | rw[key] = xx 32 | if m.Check() { 33 | //fmt.Println("is a rb tree,len:", m.Len()) 34 | } else { 35 | fmt.Println("add") 36 | return 37 | // check rb tree 38 | } 39 | } 40 | 41 | if m.Check() { 42 | fmt.Println("is a rb tree,len:", m.Len()) 43 | } 44 | 45 | for k, v := range rw { 46 | vv, ok := m.Get(k) 47 | if !ok { 48 | fmt.Println("err") 49 | return 50 | } 51 | 52 | if vv != v { 53 | fmt.Println("1 err", vv, v) 54 | return 55 | } 56 | } 57 | 58 | // 8. delete many 59 | for i := 0; i < num; i++ { 60 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 61 | //fmt.Println("delete key:", key) 62 | m.Delete(key) 63 | delete(rw, key) 64 | if m.Check() { 65 | //fmt.Println("is a rb tree,len:", m.Len()) 66 | } else { 67 | return 68 | // check rb tree 69 | } 70 | } 71 | 72 | for k, v := range rw { 73 | vv, ok := m.Get(k) 74 | if !ok { 75 | fmt.Println("err") 76 | return 77 | } 78 | 79 | if vv != v { 80 | fmt.Println("err", vv, v) 81 | return 82 | } 83 | } 84 | 85 | // 3. can iterator 86 | //iterator := m.Iterator() 87 | //for iterator.HasNext() { 88 | // k, v := iterator.Next() 89 | // fmt.Printf("Iterator key:%s,value %v\n", k, v) 90 | //} 91 | 92 | // 4. get key 93 | key := "9" 94 | value, exist := m.Get(key) 95 | if exist { 96 | fmt.Printf("%s exist, value is:%s\n", key, value) 97 | } else { 98 | fmt.Printf("%s not exist\n", key) 99 | } 100 | 101 | // 5. get int will err 102 | _, _, err := m.GetInt(key) 103 | if err != nil { 104 | fmt.Println(err.Error()) 105 | } 106 | 107 | // 6. check is a rb tree 108 | if m.Check() { 109 | fmt.Println("is a rb tree,len:", m.Len()) 110 | } 111 | 112 | // 7. delete '9' then find '9' 113 | m.Delete(key) 114 | value, exist = m.Get(key) 115 | if exist { 116 | fmt.Printf("%s exist, value is:%s\n", key, value) 117 | } else { 118 | fmt.Printf("%s not exist\n", key) 119 | } 120 | 121 | // 8. delete many 122 | for i := 0; i < num; i++ { 123 | key := fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 124 | //fmt.Println("delete key:", key) 125 | xx := key + fmt.Sprintf("_%v", rand.Int63n(int64(randNum))) 126 | m.Put(key, xx) 127 | rw[key] = xx 128 | if m.Check() { 129 | // //fmt.Println("is a rb tree,len:", m.Len()) 130 | } else { 131 | // check rb tree 132 | } 133 | 134 | key = fmt.Sprintf("%d", rand.Int63n(int64(randNum))) 135 | m.Delete(key) 136 | delete(rw, key) 137 | if m.Check() { 138 | // //fmt.Println("is a rb tree,len:", m.Len()) 139 | } else { 140 | return 141 | // check rb tree 142 | } 143 | } 144 | 145 | for k, v := range rw { 146 | vv, ok := m.Get(k) 147 | if !ok { 148 | fmt.Println("err") 149 | return 150 | } 151 | 152 | if vv != v { 153 | fmt.Println("err", vv, v) 154 | return 155 | } 156 | } 157 | 158 | // 9. key list 159 | //fmt.Printf("keyList:%#v,len:%d\n", m.KeyList(), m.Len()) 160 | //fmt.Printf("keySortList:%#v,len:%d\n", m.KeySortedList(), m.Len()) 161 | 162 | // 10. check is a rb tree 163 | if m.Check() { 164 | fmt.Println("is a rb tree,len:", m.Len()) 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /queue.go: -------------------------------------------------------------------------------- 1 | /* 2 | All right reserved:https://github.com/hunterhug/gomap at 2020 3 | Attribution-NonCommercial-NoDerivatives 4.0 International 4 | You can use it for education only but can't make profits for any companies and individuals! 5 | */ 6 | package gomap 7 | 8 | import ( 9 | "sync" 10 | ) 11 | 12 | // use queue implement iterator 13 | type linkQueue struct { 14 | root *linkNode // 链表起点 15 | size int // 队列的元素数量 16 | lock sync.Mutex // 为了并发安全使用的锁 17 | } 18 | 19 | // link node 20 | type linkNode struct { 21 | next *linkNode 22 | value bsTreeNode 23 | } 24 | 25 | // HasNext has next, queue size > 0 26 | func (queue *linkQueue) HasNext() bool { 27 | if queue.size > 0 { 28 | return true 29 | } 30 | 31 | return false 32 | } 33 | 34 | func (queue *linkQueue) Next() (key string, value interface{}) { 35 | // 不断出队列 36 | element := queue.remove() 37 | 38 | // panic here 39 | if element == nil { 40 | panic("Next() empty") 41 | } 42 | 43 | // 左子树非空,入队列 44 | if element.leftOf() != nil { 45 | queue.add(element.leftOf()) 46 | } 47 | 48 | // 右子树非空,入队列 49 | if element.rightOf() != nil { 50 | queue.add(element.rightOf()) 51 | } 52 | 53 | //if element == nil { 54 | // panic("Next() 2empty") 55 | //} 56 | return element.values() 57 | } 58 | 59 | // 入队 60 | func (queue *linkQueue) add(v bsTreeNode) { 61 | queue.lock.Lock() 62 | defer queue.lock.Unlock() 63 | 64 | // 如果栈顶为空,那么增加节点 65 | if queue.root == nil { 66 | queue.root = new(linkNode) 67 | queue.root.value = v 68 | } else { 69 | // 否则新元素插入链表的末尾 70 | // 新节点 71 | newNode := new(linkNode) 72 | newNode.value = v 73 | 74 | // 一直遍历到链表尾部 75 | nowNode := queue.root 76 | for nowNode.next != nil { 77 | nowNode = nowNode.next 78 | } 79 | 80 | // 新节点放在链表尾部 81 | nowNode.next = newNode 82 | } 83 | 84 | // 队中元素数量+1 85 | queue.size++ 86 | } 87 | 88 | // 出队 89 | func (queue *linkQueue) remove() bsTreeNode { 90 | queue.lock.Lock() 91 | defer queue.lock.Unlock() 92 | 93 | // 队中元素已空 94 | if queue.size == 0 { 95 | //panic("over limit") 96 | return nil 97 | } 98 | 99 | // 顶部元素要出队 100 | topNode := queue.root 101 | v := topNode.value 102 | 103 | // 将顶部元素的后继链接链上 104 | queue.root = topNode.next 105 | 106 | // 队中元素数量-1 107 | queue.size-- 108 | 109 | return v 110 | } -------------------------------------------------------------------------------- /queue_test.go: -------------------------------------------------------------------------------- 1 | package gomap 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "testing" 7 | ) 8 | 9 | func TestAvlBetterTree_Delete(t *testing.T) { 10 | tree := avlBetterTreeNode{} 11 | 12 | tree.balanceFactor++ 13 | fmt.Println(tree) 14 | 15 | tree.balanceFactor += 1 16 | 17 | fmt.Println(tree) 18 | 19 | rand.Seed(1000000) 20 | for i := 0; i < 100; i++ { 21 | fmt.Println(rand.Int63n(1000000)) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /rbtree.go: -------------------------------------------------------------------------------- 1 | /* 2 | All right reserved:https://github.com/hunterhug/gomap at 2020 3 | Attribution-NonCommercial-NoDerivatives 4.0 International 4 | You can use it for education only but can't make profits for any companies and individuals! 5 | */ 6 | package gomap 7 | 8 | import ( 9 | "errors" 10 | "fmt" 11 | "sync" 12 | ) 13 | 14 | const ( 15 | RED = true 16 | BLACK = false 17 | ) 18 | 19 | // ReflectError type reflect err 20 | func ReflectError(v interface{}) error { 21 | return errors.New(fmt.Sprintf("type is %T, value is:%#v", v, v)) 22 | } 23 | 24 | // red-black tree, short call rbt 25 | // refer Java TreeMap 26 | type rbTree struct { 27 | c comparator // tree key compare 28 | root *rbTNode // tree root node 29 | len int64 // tree key pairs num 30 | sync.Mutex // lock for concurrent safe 31 | } 32 | 33 | // rbt node 34 | // all field is lowercase to keep black box 35 | type rbTNode struct { 36 | k string // key 37 | v interface{} // value 38 | left *rbTNode // left tree 39 | right *rbTNode // right tree 40 | parent *rbTNode // node's parent 41 | color bool // color of parent point to this node 42 | } 43 | 44 | func (node *rbTNode) height() int64 { 45 | if node == nil { 46 | return 0 47 | } 48 | 49 | lh := node.left.height() 50 | rh := node.right.height() 51 | if lh > rh { 52 | return lh + 1 53 | } else { 54 | return rh + 1 55 | } 56 | } 57 | 58 | func (tree *rbTree) Height() int64 { 59 | return tree.root.height() 60 | } 61 | 62 | // is rbt node is red 63 | func isRed(node *rbTNode) bool { 64 | if node == nil { 65 | return false 66 | } 67 | return node.color == RED 68 | } 69 | 70 | // 返回节点的父亲节点 71 | func parentOf(node *rbTNode) *rbTNode { 72 | if node == nil { 73 | return nil 74 | } 75 | 76 | return node.parent 77 | } 78 | 79 | // 返回节点的左子节点 80 | func leftOf(node *rbTNode) *rbTNode { 81 | if node == nil { 82 | return nil 83 | } 84 | 85 | return node.left 86 | } 87 | 88 | // 返回节点的右子节点 89 | func rightOf(node *rbTNode) *rbTNode { 90 | if node == nil { 91 | return nil 92 | } 93 | 94 | return node.right 95 | } 96 | 97 | // 设置节点颜色 98 | func setColor(node *rbTNode, color bool) { 99 | if node != nil { 100 | node.color = color 101 | } 102 | } 103 | 104 | func (tree *rbTree) SetComparator(c comparator) Map { 105 | tree.Lock() 106 | defer tree.Unlock() 107 | if tree.len == 0 { 108 | tree.c = c 109 | } 110 | 111 | return tree 112 | } 113 | 114 | // 对某节点左旋转 115 | func (tree *rbTree) rotateLeft(h *rbTNode) { 116 | if h != nil { 117 | 118 | // 看图理解 119 | x := h.right 120 | h.right = x.left 121 | 122 | if x.left != nil { 123 | x.left.parent = h 124 | } 125 | 126 | x.parent = h.parent 127 | if h.parent == nil { 128 | tree.root = x 129 | } else if h.parent.left == h { 130 | h.parent.left = x 131 | } else { 132 | h.parent.right = x 133 | } 134 | x.left = h 135 | h.parent = x 136 | } 137 | } 138 | 139 | // 对某节点右旋转 140 | func (tree *rbTree) rotateRight(h *rbTNode) { 141 | if h != nil { 142 | 143 | // 看图理解 144 | x := h.left 145 | h.left = x.right 146 | 147 | if x.right != nil { 148 | x.right.parent = h 149 | } 150 | 151 | x.parent = h.parent 152 | if h.parent == nil { 153 | tree.root = x 154 | } else if h.parent.right == h { 155 | h.parent.right = x 156 | } else { 157 | h.parent.left = x 158 | } 159 | x.right = h 160 | h.parent = x 161 | } 162 | } 163 | 164 | // Put 普通红黑树添加元素 165 | func (tree *rbTree) Put(key string, value interface{}) { 166 | // add lock 167 | tree.Lock() 168 | defer tree.Unlock() 169 | //fmt.Println("add,", key) 170 | 171 | // 根节点为空 172 | if tree.root == nil { 173 | // 根节点都是黑色 174 | tree.root = &rbTNode{ 175 | k: key, 176 | v: value, 177 | color: BLACK, 178 | } 179 | tree.len = 1 180 | return 181 | } 182 | 183 | // 辅助变量 t,表示新元素要插入到该子树,t是该子树的根节点 184 | t := tree.root 185 | 186 | // 插入元素后,插入元素的父亲节点 187 | var parent *rbTNode 188 | 189 | // 辅助变量,为了知道元素最后要插到左边还是右边 190 | var cmp int64 = 0 191 | 192 | for { 193 | parent = t 194 | 195 | cmp = tree.c(key, t.k) 196 | if cmp < 0 { 197 | // 比当前节点小,往左子树插入 198 | t = t.left 199 | } else if cmp > 0 { 200 | // 比当前节点节点大,往右子树插入 201 | t = t.right 202 | } else { 203 | // update new value 204 | t.v = value 205 | return 206 | } 207 | 208 | // 终于找到要插入的位置了 209 | if t == nil { 210 | break // 这时叶子节点是 parent,要插入到 parent 的下面,跳到外层去 211 | } 212 | } 213 | 214 | // 新节点,它要插入到 parent下面 215 | newNode := &rbTNode{ 216 | k: key, 217 | v: value, 218 | parent: parent, 219 | } 220 | if cmp < 0 { 221 | // 知道要从左边插进去 222 | parent.left = newNode 223 | } else { 224 | // 知道要从右边插进去 225 | parent.right = newNode 226 | } 227 | 228 | // 插入新节点后,可能破坏了红黑树特征,需要修复,核心函数 229 | tree.fixAfterInsertion(newNode) 230 | 231 | // len add 1 232 | tree.len++ 233 | } 234 | 235 | // 调整新插入的节点,自底而上 236 | // 可以看图理解 237 | func (tree *rbTree) fixAfterInsertion(node *rbTNode) { 238 | // 插入的新节点一定要是红色 239 | node.color = RED 240 | 241 | // 节点不能是空,不能是根节点,父亲的颜色必须为红色(如果是黑色,那么直接插入不破坏平衡,不需要调整了) 242 | for node != nil && node != tree.root && node.parent.color == RED { 243 | // 父亲在祖父的左边 244 | if parentOf(node) == leftOf(parentOf(parentOf(node))) { 245 | // 叔叔节点 246 | uncle := rightOf(parentOf(parentOf(node))) 247 | 248 | // 图例3左边部分,叔叔是红节点,祖父变色,也就是父亲和叔叔变黑,祖父变红 249 | if isRed(uncle) { 250 | setColor(parentOf(node), BLACK) 251 | setColor(uncle, BLACK) 252 | setColor(parentOf(parentOf(node)), RED) 253 | // 还要向上递归 254 | node = parentOf(parentOf(node)) 255 | } else { 256 | // 图例4左边部分,叔叔是黑节点,并且插入的节点在父亲的右边,需要对父亲左旋 257 | if node == rightOf(parentOf(node)) { 258 | node = parentOf(node) 259 | tree.rotateLeft(node) 260 | } 261 | 262 | // 变色,并对祖父进行右旋 263 | setColor(parentOf(node), BLACK) 264 | setColor(parentOf(parentOf(node)), RED) 265 | tree.rotateRight(parentOf(parentOf(node))) 266 | } 267 | } else { 268 | // 父亲在祖父的右边,与父亲在祖父的左边相似 269 | // 叔叔节点 270 | uncle := leftOf(parentOf(parentOf(node))) 271 | 272 | // 图例3右边部分,叔叔是红节点,祖父变色,也就是父亲和叔叔变黑,祖父变红 273 | if isRed(uncle) { 274 | setColor(parentOf(node), BLACK) 275 | setColor(uncle, BLACK) 276 | setColor(parentOf(parentOf(node)), RED) 277 | // 还要向上递归 278 | node = parentOf(parentOf(node)) 279 | } else { 280 | // 图例4右边部分,叔叔是黑节点,并且插入的节点在父亲的左边,需要对父亲右旋 281 | if node == leftOf(parentOf(node)) { 282 | node = parentOf(node) 283 | tree.rotateRight(node) 284 | } 285 | 286 | // 变色,并对祖父进行左旋 287 | setColor(parentOf(node), BLACK) 288 | setColor(parentOf(parentOf(node)), RED) 289 | tree.rotateLeft(parentOf(parentOf(node))) 290 | } 291 | } 292 | } 293 | 294 | // 根节点永远为黑 295 | tree.root.color = BLACK 296 | } 297 | 298 | // Delete 普通红黑树删除元素 299 | func (tree *rbTree) Delete(key string) { 300 | tree.Lock() 301 | defer tree.Unlock() 302 | 303 | if tree.root == nil { 304 | return 305 | } 306 | 307 | // 查找元素是否存在,不存在则退出 308 | // should inline like c++, describe func call 309 | node := tree.find(key) 310 | if node == nil { 311 | return 312 | } 313 | 314 | //fmt.Println("delete,", key) 315 | // 删除该节点 316 | tree.delete(node) 317 | 318 | tree.len-- 319 | } 320 | 321 | // 删除节点核心函数 322 | // 找最小后驱节点来补位,删除内部节点转为删除叶子节点 323 | func (tree *rbTree) delete(node *rbTNode) { 324 | // 如果左右子树都存在,那么从右子树的左边一直找一直找,就找能到最小后驱节点 325 | if node.left != nil && node.right != nil { 326 | s := node.right 327 | for s.left != nil { 328 | s = s.left 329 | } 330 | 331 | // 删除的叶子节点找到了,删除内部节点转为删除叶子节点 332 | node.k = s.k 333 | node.v = s.v 334 | node = s // node may be has one right son 335 | } 336 | 337 | if node.left == nil && node.right == nil { 338 | // 没有子树,要删除的节点就是叶子节点。 339 | } else { 340 | // 只有一棵子树,因为红黑树的特征,该子树就只有一个节点 341 | // 找到该唯一节点 342 | replacement := node.left 343 | if node.left == nil { 344 | replacement = node.right 345 | } 346 | 347 | // 替换开始,子树的唯一节点替代被删除的内部节点 348 | replacement.parent = node.parent 349 | 350 | if node.parent == nil { 351 | // 要删除的节点的父亲为空,表示要删除的节点为根节点,唯一子节点成为树根 352 | tree.root = replacement 353 | } else if node == node.parent.left { 354 | // 子树的唯一节点替代被删除的内部节点 355 | node.parent.left = replacement 356 | } else { 357 | // 子树的唯一节点替代被删除的内部节点 358 | node.parent.right = replacement 359 | } 360 | 361 | // delete this node 362 | node.parent = nil 363 | node.right = nil 364 | node.left = nil 365 | 366 | // case 1: not enter this logic 367 | // R(del) 368 | // B B 369 | // 370 | // case 2: node's color must be black, and it's son must be red 371 | // B(del) B(del) 372 | // R O O R 373 | // 374 | // 单子树时删除的节点绝对是黑色的,而其唯一子节点必然是红色的 375 | // 现在唯一子节点替换了被删除节点,该节点要变为黑色 376 | // now son replace it's father, just change color to black 377 | replacement.color = BLACK 378 | 379 | //// 要删除的节点,是一个黑节点,删除后会破坏平衡,需要进行调整,调整成可以删除的状态 380 | //if !isRed(node) { 381 | // // 核心函数 382 | // tree.fixAfterDeletion(replacement) 383 | //} 384 | 385 | return 386 | } 387 | 388 | // 要删除的叶子节点没有父亲,那么它是根节点,直接置空,返回 389 | if node.parent == nil { 390 | //fmt.Println("root") 391 | tree.root = nil 392 | return 393 | } 394 | 395 | // 要删除的叶子节点,是一个黑节点,删除后会破坏平衡,需要进行调整,调整成可以删除的状态 396 | if !isRed(node) { 397 | // 核心函数 398 | tree.fixAfterDeletion(node) 399 | } 400 | 401 | // 现在可以删除叶子节点了 402 | if node == node.parent.left { 403 | node.parent.left = nil 404 | } else if node == node.parent.right { 405 | node.parent.right = nil 406 | } 407 | 408 | node.parent = nil 409 | } 410 | 411 | // 调整删除的叶子节点,自底向上 412 | // 可以看图理解 413 | func (tree *rbTree) fixAfterDeletion(node *rbTNode) { 414 | // 如果不是递归到根节点,且节点是黑节点,那么继续递归 415 | for tree.root != node && !isRed(node) { 416 | // 要删除的节点在父亲左边,对应图例1,2 417 | if node == leftOf(parentOf(node)) { 418 | // 找出兄弟 419 | brother := rightOf(parentOf(node)) 420 | 421 | // 兄弟是红色的,对应图例1,那么兄弟变黑,父亲变红,然后对父亲左旋,进入图例21,22,23 422 | if isRed(brother) { 423 | setColor(brother, BLACK) 424 | setColor(parentOf(node), RED) 425 | tree.rotateLeft(parentOf(node)) 426 | brother = rightOf(parentOf(node)) // 图例1调整后进入图例21,22,23,兄弟此时变了 427 | } 428 | 429 | // 兄弟是黑色的,对应图例21,22,23 430 | // 兄弟的左右儿子都是黑色,进入图例23,将兄弟设为红色,父亲所在的子树作为整体,当作删除的节点,继续向上递归 431 | if !isRed(leftOf(brother)) && !isRed(rightOf(brother)) { 432 | setColor(brother, RED) 433 | node = parentOf(node) 434 | } else { 435 | // 兄弟的右儿子是黑色,进入图例22,将兄弟设为红色,兄弟的左儿子设为黑色,对兄弟右旋,进入图例21 436 | if !isRed(rightOf(brother)) { 437 | setColor(leftOf(brother), BLACK) 438 | setColor(brother, RED) 439 | tree.rotateRight(brother) 440 | brother = rightOf(parentOf(node)) // 图例22调整后进入图例21,兄弟此时变了 441 | } 442 | 443 | // 兄弟的右儿子是红色,进入图例21,将兄弟设置为父亲的颜色,兄弟的右儿子以及父亲变黑,对父亲左旋 444 | setColor(brother, parentOf(node).color) 445 | setColor(parentOf(node), BLACK) 446 | setColor(rightOf(brother), BLACK) 447 | tree.rotateLeft(parentOf(node)) 448 | 449 | node = tree.root 450 | } 451 | } else { 452 | // 要删除的节点在父亲右边,对应图例3,4 453 | // 找出兄弟 454 | brother := leftOf(parentOf(node)) 455 | 456 | // 兄弟是红色的,对应图例3,那么兄弟变黑,父亲变红,然后对父亲右旋,进入图例41,42,43 457 | if isRed(brother) { 458 | setColor(brother, BLACK) 459 | setColor(parentOf(node), RED) 460 | tree.rotateRight(parentOf(node)) 461 | brother = leftOf(parentOf(node)) // 图例3调整后进入图例41,42,43,兄弟此时变了 462 | } 463 | 464 | // 兄弟是黑色的,对应图例41,42,43 465 | // 兄弟的左右儿子都是黑色,进入图例43,将兄弟设为红色,父亲所在的子树作为整体,当作删除的节点,继续向上递归 466 | if !isRed(leftOf(brother)) && !isRed(rightOf(brother)) { 467 | setColor(brother, RED) 468 | node = parentOf(node) 469 | } else { 470 | // 兄弟的左儿子是黑色,进入图例42,将兄弟设为红色,兄弟的右儿子设为黑色,对兄弟左旋,进入图例41 471 | if !isRed(leftOf(brother)) { 472 | setColor(rightOf(brother), BLACK) 473 | setColor(brother, RED) 474 | tree.rotateLeft(brother) 475 | brother = leftOf(parentOf(node)) // 图例42调整后进入图例41,兄弟此时变了 476 | } 477 | 478 | // 兄弟的左儿子是红色,进入图例41,将兄弟设置为父亲的颜色,兄弟的左儿子以及父亲变黑,对父亲右旋 479 | setColor(brother, parentOf(node).color) 480 | setColor(parentOf(node), BLACK) 481 | setColor(leftOf(brother), BLACK) 482 | tree.rotateRight(parentOf(node)) 483 | 484 | node = tree.root 485 | } 486 | } 487 | } 488 | 489 | // this node always black 490 | setColor(node, BLACK) 491 | } 492 | 493 | // MinKey find min key pairs 494 | func (tree *rbTree) MinKey() (key string, value interface{}, exist bool) { 495 | // add lock 496 | tree.Lock() 497 | defer tree.Unlock() 498 | if tree.root == nil { 499 | // 如果是空树,返回空 500 | return 501 | } 502 | 503 | node := tree.root.minNode() 504 | return node.k, node.v, true 505 | } 506 | 507 | func (node *rbTNode) minNode() *rbTNode { 508 | // 左子树为空,表面已经是最左的节点了,该值就是最小值 509 | if node.left == nil { 510 | return node 511 | } 512 | 513 | // 一直左子树递归 514 | return node.left.minNode() 515 | } 516 | 517 | // MaxKey find max key pairs 518 | func (tree *rbTree) MaxKey() (key string, value interface{}, exist bool) { 519 | // add lock 520 | tree.Lock() 521 | defer tree.Unlock() 522 | if tree.root == nil { 523 | // 如果是空树,返回空 524 | return 525 | } 526 | 527 | node := tree.root.maxNode() 528 | return node.k, node.v, true 529 | } 530 | 531 | func (node *rbTNode) maxNode() *rbTNode { 532 | // 右子树为空,表面已经是最右的节点了,该值就是最大值 533 | if node.right == nil { 534 | return node 535 | } 536 | 537 | // 一直右子树递归 538 | return node.right.maxNode() 539 | } 540 | 541 | // Get 查找指定节点 542 | func (tree *rbTree) Get(key string) (value interface{}, exist bool) { 543 | tree.Lock() 544 | defer tree.Unlock() 545 | if tree.root == nil { 546 | return 547 | } 548 | 549 | node := tree.find(key) 550 | if node != nil { 551 | return node.v, true 552 | } 553 | 554 | return 555 | } 556 | 557 | // Contains 查找指定节点 558 | func (tree *rbTree) Contains(key string) (exist bool) { 559 | tree.Lock() 560 | defer tree.Unlock() 561 | if tree.root == nil { 562 | return false 563 | } 564 | 565 | if tree.find(key) == nil { 566 | return false 567 | } else { 568 | return true 569 | } 570 | } 571 | 572 | func (tree *rbTree) Len() int64 { 573 | return tree.len 574 | } 575 | 576 | func (tree *rbTree) GetInt(key string) (value int, exist bool, err error) { 577 | var v interface{} 578 | v, exist = tree.Get(key) 579 | if !exist { 580 | return 581 | } 582 | 583 | value, ok := v.(int) 584 | if !ok { 585 | err = ReflectError(v) 586 | return 587 | } 588 | 589 | return value, true, nil 590 | } 591 | 592 | func (tree *rbTree) GetInt64(key string) (value int64, exist bool, err error) { 593 | var v interface{} 594 | v, exist = tree.Get(key) 595 | if !exist { 596 | return 597 | } 598 | 599 | value, ok := v.(int64) 600 | if !ok { 601 | err = ReflectError(v) 602 | return 603 | } 604 | 605 | return value, true, nil 606 | } 607 | 608 | func (tree *rbTree) GetString(key string) (value string, exist bool, err error) { 609 | var v interface{} 610 | v, exist = tree.Get(key) 611 | if !exist { 612 | return 613 | } 614 | 615 | value, ok := v.(string) 616 | if !ok { 617 | err = ReflectError(v) 618 | return 619 | } 620 | 621 | return value, true, nil 622 | } 623 | 624 | func (tree *rbTree) GetFloat64(key string) (value float64, exist bool, err error) { 625 | var v interface{} 626 | v, exist = tree.Get(key) 627 | if !exist { 628 | return 629 | } 630 | 631 | value, ok := v.(float64) 632 | if !ok { 633 | err = ReflectError(v) 634 | return 635 | } 636 | 637 | return value, true, nil 638 | } 639 | 640 | func (tree *rbTree) GetBytes(key string) (value []byte, exist bool, err error) { 641 | var v interface{} 642 | v, exist = tree.Get(key) 643 | if !exist { 644 | return 645 | } 646 | 647 | value, ok := v.([]byte) 648 | if !ok { 649 | err = ReflectError(v) 650 | return 651 | } 652 | 653 | return value, true, nil 654 | } 655 | 656 | // find key in tree 657 | func (tree *rbTree) find(key string) *rbTNode { 658 | node := tree.root 659 | for { 660 | cmp := tree.c(key, node.k) 661 | if cmp == 0 { 662 | return node 663 | } else if cmp < 0 { 664 | node = node.left 665 | } else { 666 | node = node.right 667 | } 668 | 669 | if node == nil { 670 | return nil 671 | } 672 | } 673 | } 674 | 675 | // KeySortedList 中序遍历 676 | // mid order get key list 677 | func (tree *rbTree) KeySortedList() []string { 678 | // add lock 679 | tree.Lock() 680 | defer tree.Unlock() 681 | keyList := make([]string, 0, tree.len) 682 | return tree.root.midOrder(keyList) 683 | } 684 | 685 | func (node *rbTNode) midOrder(keyList []string) []string { 686 | if node == nil { 687 | return keyList 688 | } 689 | 690 | // 先打印左子树 691 | keyList = node.left.midOrder(keyList) 692 | 693 | keyList = append(keyList, node.k) 694 | 695 | // 打印右子树 696 | keyList = node.right.midOrder(keyList) 697 | 698 | return keyList 699 | } 700 | 701 | // Check 验证是不是棵红黑树 702 | func (tree *rbTree) Check() bool { 703 | if tree == nil || tree.root == nil { 704 | return true 705 | } 706 | 707 | // 判断树是否是一棵二分查找树 708 | if !tree.root.isBST(tree.c) { 709 | fmt.Println("is not BST") 710 | return false 711 | } 712 | 713 | // 判断树是否遵循2-3-4树,也就是不能有连续的两个红链接 714 | if !tree.root.is234() { 715 | fmt.Println("is not 234 tree") 716 | return false 717 | } 718 | 719 | // 判断树是否平衡,也就是任意一个节点到叶子节点,经过的黑色链接数量相同 720 | // 先计算根节点到最左边叶子节点的黑链接数量 721 | blackNum := 0 722 | x := tree.root 723 | for x != nil { 724 | if !isRed(x) { // 是黑色链接 725 | blackNum = blackNum + 1 726 | } 727 | x = x.left 728 | } 729 | 730 | if !tree.root.isBalanced(blackNum) { 731 | fmt.Println("is not Balanced") 732 | return false 733 | } 734 | return true 735 | } 736 | 737 | // 节点所在的子树是否是一棵二分查找树 738 | func (node *rbTNode) isBST(c comparator) bool { 739 | if node == nil { 740 | return true 741 | } 742 | 743 | // 左子树非空,那么根节点必须大于左儿子节点 744 | if node.left != nil { 745 | cmp := c(node.k, node.left.k) 746 | if cmp > 0 { 747 | } else { 748 | fmt.Printf("father:%#v,lchild:%#v,rchild:%#v\n", node, node.left, node.right) 749 | return false 750 | } 751 | } 752 | 753 | // 右子树非空,那么根节点必须小于右儿子节点 754 | if node.right != nil { 755 | cmp := c(node.k, node.right.k) 756 | if cmp < 0 { 757 | } else { 758 | fmt.Printf("father:%#v,lchild:%#v,rchild:%#v\n", node, node.left, node.right) 759 | return false 760 | } 761 | } 762 | 763 | // 左子树也要判断是否是平衡查找树 764 | if !node.left.isBST(c) { 765 | return false 766 | } 767 | 768 | // 右子树也要判断是否是平衡查找树 769 | if !node.right.isBST(c) { 770 | return false 771 | } 772 | 773 | return true 774 | } 775 | 776 | // 节点所在的子树是否遵循2-3-4树 777 | func (node *rbTNode) is234() bool { 778 | if node == nil { 779 | return true 780 | } 781 | 782 | // 不允许连续两个左红链接 783 | if isRed(node) && isRed(node.left) { 784 | fmt.Printf("father:%#v,lchild:%#v\n", node, node.left) 785 | return false 786 | } 787 | 788 | if isRed(node) && isRed(node.right) { 789 | fmt.Printf("father:%#v,rchild:%#v\n", node, node.right) 790 | return false 791 | } 792 | 793 | // 左子树也要判断是否遵循2-3-4树 794 | if !node.left.is234() { 795 | return false 796 | } 797 | 798 | // 右子树也要判断是否是遵循2-3-4树 799 | if !node.right.is234() { 800 | return false 801 | } 802 | 803 | return true 804 | } 805 | 806 | // 节点所在的子树是否平衡,是否有 blackNum 个黑链接 807 | func (node *rbTNode) isBalanced(blackNum int) bool { 808 | if node == nil { 809 | return blackNum == 0 810 | } 811 | 812 | if !isRed(node) { 813 | blackNum = blackNum - 1 814 | } 815 | 816 | if !node.left.isBalanced(blackNum) { 817 | fmt.Println("node.left to leaf black link is not ", blackNum) 818 | return false 819 | } 820 | 821 | if !node.right.isBalanced(blackNum) { 822 | fmt.Println("node.right to leaf black link is not ", blackNum) 823 | return false 824 | } 825 | 826 | return true 827 | } 828 | 829 | // iterator help struct 830 | type bsTreeNode interface { 831 | leftOf() bsTreeNode 832 | rightOf() bsTreeNode 833 | values() (key string, value interface{}) 834 | } 835 | 836 | // 返回节点的左子节点 837 | func (node *rbTNode) leftOf() bsTreeNode { 838 | if node.left == nil { 839 | return nil 840 | } 841 | 842 | return node.left 843 | } 844 | 845 | // 返回节点的右子节点 846 | func (node *rbTNode) rightOf() bsTreeNode { 847 | if node.right == nil { 848 | return nil 849 | } 850 | 851 | return node.right 852 | } 853 | 854 | // not check node nil, may be panic, user should deal by oneself 855 | func (node *rbTNode) values() (key string, value interface{}) { 856 | return node.k, node.v 857 | } 858 | 859 | func (tree *rbTree) KeyList() []string { 860 | tree.Lock() 861 | defer tree.Unlock() 862 | 863 | if tree.root == nil { 864 | return []string{} 865 | } 866 | 867 | keyList := make([]string, 0, tree.len) 868 | iterator := tree.Iterator() 869 | for iterator.HasNext() { 870 | k, _ := iterator.Next() 871 | keyList = append(keyList, k) 872 | } 873 | 874 | return keyList 875 | 876 | } 877 | 878 | func (tree *rbTree) Iterator() MapIterator { 879 | q := new(linkQueue) 880 | if tree.root != nil { 881 | q.add(tree.root) 882 | } 883 | return q 884 | } --------------------------------------------------------------------------------