Skip to content

Commit acfcb68

Browse files
committed
add
1 parent 6adfa75 commit acfcb68

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

jiuzhangsuanfa/skiplist/skiplist.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package skiplist
2+
3+
import (
4+
"math"
5+
"math/rand"
6+
"time"
7+
8+
)
9+
10+
func init() {
11+
rand.Seed(time.Now().UTC().UnixNano())
12+
}
13+
14+
type node struct {
15+
Lesser
16+
nexts []*node
17+
}
18+
19+
type skiplist struct {
20+
header node
21+
size int
22+
}
23+
24+
// New create a skiplist instance
25+
func New(estimatedNodeCount int) MapContainer {
26+
if estimatedNodeCount < 2 {
27+
estimatedNodeCount = 2
28+
}
29+
return &skiplist{header: node{nexts: make([]*node,
30+
int64(math.Ceil(math.Log2(float64(estimatedNodeCount)))))}}
31+
}
32+
33+
func isEqual(ls1 Lesser, ls2 Lesser) bool {
34+
return !ls1.Less(ls2) && !ls2.Less(ls1)
35+
}
36+
37+
// ReplaceOrInsert insert a element or replace the element if it already exists
38+
func (sl *skiplist) ReplaceOrInsert(elem Lesser) Lesser {
39+
insertToHeight := calcInsertionHeight(len(sl.header.nexts))
40+
newNode := &node{elem, make([]*node, insertToHeight)}
41+
prevs, removed := sl.removeIfAny(elem)
42+
if removed == nil {
43+
sl.size++
44+
}
45+
46+
for i := 0; i < len(newNode.nexts); i++ {
47+
newNode.nexts[i] = prevs[i].nexts[i]
48+
prevs[i].nexts[i] = newNode
49+
}
50+
return newNode
51+
}
52+
53+
func (sl *skiplist) getMaxHeight() int {
54+
return len(sl.header.nexts)
55+
}
56+
57+
func (sl *skiplist) searchPrev(target Lesser) []*node {
58+
prevs := make([]*node, sl.getMaxHeight()+1)
59+
prevs[len(prevs)-1] = &sl.header
60+
for h := sl.getMaxHeight() - 1; h >= 0; h-- {
61+
prevs[h] = prevs[h+1]
62+
for pv := prevs[h].nexts[h]; pv != nil && pv.Lesser.Less(target); pv = pv.nexts[h] {
63+
prevs[h] = pv
64+
}
65+
}
66+
return prevs[:len(prevs)-1]
67+
}
68+
69+
// Search search an element in skiplist
70+
func (sl *skiplist) Search(target Lesser) (Lesser, bool) {
71+
prevs := sl.searchPrev(target)
72+
if prevs[0].nexts[0] != nil && isEqual(prevs[0].nexts[0].Lesser, target) {
73+
return prevs[0].nexts[0].Lesser, true
74+
}
75+
return nil, false
76+
}
77+
func remove(prevs []*node, target Lesser) (deleted *node) {
78+
for i := 0; i < len(prevs) && prevs[i].nexts[i] != nil && isEqual(prevs[i].nexts[i].Lesser, target); i++ {
79+
deleted = prevs[i].nexts[i]
80+
prevs[i].nexts[i] = prevs[i].nexts[i].nexts[i]
81+
}
82+
return
83+
}
84+
func (sl *skiplist) removeIfAny(target Lesser) (prevs []*node, deleted *node) {
85+
prevs = sl.searchPrev(target)
86+
deleted = remove(prevs, target)
87+
return
88+
}
89+
90+
func calcInsertionHeight(maxHeight int) int {
91+
res := 1
92+
for i := 0; i < maxHeight-1; i++ {
93+
upDown := rand.Intn(2)
94+
if upDown == 0 {
95+
break
96+
}
97+
res++
98+
}
99+
return res
100+
}
101+
102+
// Delete delete the target from skiplist
103+
func (sl *skiplist) Delete(target Lesser) (deleted Lesser, found bool) {
104+
_, deletedNode := sl.removeIfAny(target)
105+
if deletedNode != nil {
106+
sl.size--
107+
return deletedNode.Lesser, true
108+
}
109+
return nil, false
110+
}
111+
112+
// Min get the element with minimum value
113+
func (sl *skiplist) Min() (Lesser, bool) {
114+
if sl.header.nexts[0] == nil {
115+
return nil, false
116+
}
117+
return sl.header.nexts[0].Lesser, true
118+
}
119+
120+
// Ascend loop over all element and run @iterHandler
121+
func (sl *skiplist) Ascend(iterHandler func(i Lesser) bool) {
122+
for next := sl.header.nexts[0]; next != nil &&
123+
iterHandler(next.Lesser); next = next.nexts[0] {
124+
}
125+
}
126+
127+
// Len return element count in skiplist
128+
func (sl *skiplist) Len() int {
129+
return sl.size
130+
}
131+
132+
func (sl *skiplist) max() ([]*node, bool) {
133+
prevs := make([]*node, sl.getMaxHeight()+1)
134+
prevs[len(prevs)-1] = &sl.header
135+
for h := sl.getMaxHeight() - 1; h >= 0; h-- {
136+
prevs[h] = prevs[h+1]
137+
for pv := prevs[h].nexts[h]; pv != nil &&
138+
pv.nexts[h] != nil; pv = pv.nexts[h] {
139+
140+
prevs[h] = pv
141+
}
142+
}
143+
if sl.size != 0 {
144+
return prevs[:len(prevs)-1], true
145+
}
146+
return nil, false
147+
}
148+
149+
// Max return maximum element in skiplist
150+
func (sl *skiplist) Max() (less Lesser, found bool) {
151+
prevs, found := sl.max()
152+
if found {
153+
return prevs[0].nexts[0].Lesser, true
154+
}
155+
return nil, false
156+
}
157+
158+
// DeleteMax delete the element with maximum value.
159+
func (sl *skiplist) DeleteMax() (less Lesser, found bool) {
160+
prevs, found := sl.max()
161+
if found {
162+
sl.size--
163+
maxLesser := prevs[0].nexts[0].Lesser
164+
return remove(prevs, maxLesser).Lesser, true
165+
}
166+
return nil, false
167+
}

0 commit comments

Comments
 (0)