github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/datastructures/sikplist/sikplist.go (about) 1 package sikplist 2 3 import ( 4 "fmt" 5 "math" 6 "math/rand" 7 "strings" 8 ) 9 10 /* 11 跳表 12 时间复杂度 13 14 1. 假设 每2个节点一个索引,最顶层索引是2, 有n个节点,每层最多遍历2+1=3个 15 设 n 个节点 , h表示层数, m表示每层遍历的次数 16 n/(2^h) = 2 => h = log2(n)-1 17 所以复杂度是 O(m*(log2(n)-1)) m是个常数级别 18 时间复杂度是 O(logn) 19 20 每3个节点一个索引 O(m*(log3(n)-1)); m = 3+1 21 22 空间复杂度 23 2节点一索引: n/2 + n/4 + n/8 +... 等比数列 约等于 约等于 n 24 所以空间复杂度 O(n) 25 26 3节点一索引: n/3 + n/9 + n/27 +... 等比数列 约等于 约等于 n/2 27 28 */ 29 const ( 30 MaxLevel = 16 31 SkiplistP = 0.5 32 ) 33 34 //跳表节点结构体 35 type skipListNode struct { 36 v interface{} // 数据 37 score int // 用于排序的分值 38 level int //层高 39 forwards []*skipListNode //每层前进指针 40 } 41 42 //新建跳表节点 43 func newSkipListNode(v interface{}, score, level int) *skipListNode { 44 return &skipListNode{ 45 v: v, 46 score: score, 47 forwards: make([]*skipListNode, level, level), 48 level: level, 49 } 50 } 51 52 func (sln *skipListNode) String() string { 53 return fmt.Sprintf("[%v %v]", sln.v, sln.score) 54 } 55 56 // 跳表结构体 57 type SkipList struct { 58 head *skipListNode //跳表头结点 59 level int //跳表当前层数 60 length int ///跳表长度 61 } 62 63 func NewSkipList() *SkipList { 64 // 头结点, 可以称为哨兵 65 head := newSkipListNode(nil, math.MinInt32, MaxLevel) 66 return &SkipList{head, 1, 0} 67 } 68 69 //获取跳表长度 70 func (sl *SkipList) Length() int { 71 return sl.length 72 } 73 74 //获取跳表层级 75 func (sl *SkipList) Level() int { 76 return sl.level 77 } 78 79 //插入节点到跳表中 80 func (sl *SkipList) Insert(v interface{}, score int) int { 81 if v == nil { 82 return 1 83 } 84 //查找插入位置 85 cur := sl.head 86 //创建数组 记录每层的路径 87 update := [MaxLevel]*skipListNode{} 88 // 从最高层开始 89 for i := MaxLevel - 1; i >= 0; i-- { 90 for ; nil != cur.forwards[i]; cur = cur.forwards[i] { // 当前层进行查找 91 if cur.forwards[i].v == v || cur.v == v { // 插入的值相等 92 return 2 93 } 94 if cur.forwards[i].score > score { // 找到了 95 update[i] = cur 96 break 97 } 98 } 99 update[i] = cur 100 } 101 102 //通过随机算法获取该节点层数 103 level := sl.randomLevel() 104 105 //创建一个新的跳表节点 106 newNode := newSkipListNode(v, score, level) 107 108 //给每层插入新结点 109 for i := 0; i < level; i++ { 110 newNode.forwards[i] = update[i].forwards[i] 111 update[i].forwards[i] = newNode 112 } 113 114 //如果当前节点的层数大于之前跳表的层数 115 //更新当前跳表层数 116 if level > sl.level { 117 sl.level = level 118 } 119 120 //更新跳表长度 121 sl.length++ 122 return 0 123 } 124 125 /* 126 一级索引中元素个数应该占原始数据的 1/2,二级索引中元素个数占 1/4,三级索引 1/8 一直到最顶层。 127 因为这里每一层的晋升概率是 50%。对于每一个新插入的节点,都需要调用 randomLevel 生成一个合理的层数。 128 该 randomLevel 方法会随机生成 1~MAX_LEVEL 之间的数, 129 50%的概率返回 1 130 25%的概率返回 2 131 12.5%的概率返回 3 ... 132 */ 133 func (sl *SkipList) randomLevel() int { 134 level := 1 135 for rand.Float32() < SkiplistP && level < MaxLevel { 136 level++ 137 } 138 return level 139 } 140 141 //查找 142 func (sl *SkipList) Find(v interface{}, score int) *skipListNode { 143 if nil == v || sl.length == 0 { 144 return nil 145 } 146 cur := sl.head 147 for i := sl.level - 1; i >= 0; i-- { 148 for ; nil != cur.forwards[i] && cur.forwards[i].score <= score; cur = cur.forwards[i] { 149 if cur.forwards[i].score == score && cur.forwards[i].v == v { 150 return cur.forwards[i] 151 } 152 } 153 } 154 return nil 155 } 156 157 // 范围查找 158 func (sl *SkipList) FindRange(start, end int) []interface{} { 159 if sl.length == 0 || end < start { 160 return nil 161 } 162 cur := sl.head.forwards[sl.level-1] 163 for i := sl.level - 1; i >= 0; i-- { 164 for ; nil != cur; cur = cur.forwards[i] { 165 if cur.score >= start { 166 break 167 } 168 } 169 } 170 if cur != nil { 171 var ret []interface{} 172 for ; cur != nil && cur.score <= end; cur = cur.forwards[0] { 173 ret = append(ret, cur.v) 174 } 175 return ret 176 } 177 return nil 178 } 179 180 //删除节点 181 func (sl *SkipList) Delete(v interface{}, score int) int { 182 if nil == v { 183 return 1 184 } 185 cur := sl.head 186 //记录前驱路径 187 update := [MaxLevel]*skipListNode{} 188 for i := sl.level - 1; i >= 0; i-- { 189 update[i] = sl.head // 默认是头结点开始 190 for ; nil != cur.forwards[i]; cur = cur.forwards[i] { 191 if cur.forwards[i].score == score && cur.forwards[i].v == v { 192 update[i] = cur 193 break 194 } 195 } 196 } 197 198 cur = update[0].forwards[0] 199 for i := cur.level - 1; i >= 0; i-- { 200 if update[i] == sl.head && cur.forwards[i] == nil { //当前层没有元素 201 sl.level = i 202 } 203 204 if nil == update[i].forwards[i] { 205 update[i].forwards[i] = nil 206 } else { 207 update[i].forwards[i] = update[i].forwards[i].forwards[i] 208 } 209 } 210 211 sl.length-- 212 return 0 213 } 214 215 func (sl *SkipList) String() string { 216 var sb strings.Builder 217 sb.WriteString(fmt.Sprintf("level:%+v, length:%+v\n", sl.level, sl.length)) 218 for i := MaxLevel - 1; i >= 0; i-- { 219 cur := sl.head.forwards[i] 220 if cur == nil { 221 continue 222 } 223 _, _ = fmt.Fprintf(&sb, "%v [head]->", i) 224 for ; cur != nil; cur = cur.forwards[i] { 225 _, _ = fmt.Fprintf(&sb, "[%v %v]->", cur.v, cur.score) 226 } 227 sb.WriteString("nil\n") 228 } 229 return sb.String() 230 }