-
Notifications
You must be signed in to change notification settings - Fork 0
/
skipList.js
88 lines (87 loc) · 2.24 KB
/
skipList.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
class SkipNode {
constructor(value, height) {
this.value = value
this.height = height
this.forward = Array(height)
}
}
class SkipList {
// maxlevel should be chosen to be approx log1/p(capacity)
constructor(maxLevel, p=0.5) {
this.tail = new SkipNode(undefined, maxLevel)
this.head = new SkipNode(undefined, maxLevel)
this.head.forward.fill(this.tail)
this.maxLevel = maxLevel
this.p = p
this.size = 0
}
find(value) {
const pre = this.predecessors(value)[0].forward[0]
if(pre && pre.value === value && pre !== this.tail)
return pre
return null
}
insert(value) {
const preds = this.predecessors(value)
const newNode = new SkipNode(value, this.randomLevel())
for(let i = 0; i < newNode.height; i++) {
newNode.forward[i] = preds[i].forward[i]
preds[i].forward[i] = newNode
}
this.size++
}
remove(value) {
const preds = this.predecessors(value)
const node = preds[0].forward[0]
if(node.value !== value || node === this.tail)
return
for(let i = 0; i < node.height; i++)
preds[i].forward[i] = node.forward[i]
this.size--
}
// Takes a number and finds the Node in the list after which the number would be inserted.
// Used as a helper function to implement the step "find where [X] would be" in each of the other operations.
predecessors(value) {
let curr = this.head
const update = Array(this.maxLevel)
for(let i = this.maxLevel; i >= 0; i--) {
while(curr.forward[i] && curr.forward[i].value < value)
curr = curr.forward[i]
update[i] = curr
}
return update
}
randomLevel() {
let i = 1
while(Math.random() < this.p && i < this.maxLevel) i++
return i
}
print() {
let list = this.head.forward[0]
let str = "{"
let ll = 0
while(list !== this.tail) {
str += `value: ${list.value}, height: ${list.height}`
list = list.forward[0]
if(list !== this.tail)
str += " : "
if(++ll % 2 === 0) str += "\n"
}
str += "}"
console.log(str)
}
}
const sl = new SkipList(4)
sl.insert(5)
sl.print()
sl.insert(5)
sl.print()
sl.insert(26)
console.log(sl.find(5))
sl.insert(55)
sl.print()
sl.insert(33)
sl.remove(5)
sl.print()
sl.remove(76876)
sl.print()