class SkipList {
constructor(max_level = 6, p = 0.5) {
this.level = 1;
this.maxLevel = max_level;
this.p = p;
this.NIL = new Node(Infinity, null, max_level, 0, null);
this.header = new Node(-Infinity, null, max_level, 0, this.NIL);
}
Insert(key, val) {
let update = newArray(this.maxLevel, this.NIL);
let prevNode = newArray(this.maxLevel, update)
let height = this.level
let x = this.header;
for (let i = this.level - 1; i >= 0; i--) {
while (x.forward[i].key < key) {
x = x.forward[i];
}
update[i] = x;
}
x = x.forward[0];
let extra = 0;
if (x.key == key) {
x.val = val;
} else {
let new_level = this.randomLevel();
if (new_level >= this.level) {
for (let i = this.level; i <= new_level; i++) {
update[i] = this.header;
}
this.level = new_level + 1;
}
x = new Node(key, val, new_level, extra, this.NIL);
for (let i = 0; i < new_level; i++) {
x.forward[i] = update[i].forward[i];
update[i].forward[i] = x;
}
let y = update[x.forward.length - 1].forward[0]
while (y != x) {
if (x.forward[0].forward > x.forward.length) {
x.forward[0].forward[0].extra += 1
}
x.extra += 1
y = y.forward[0]
}
let z = update[0].forward[0].forward[0]
let a = x.forward.length
while (z.key != Infinity) {
if (z.key > x.key) {
if (z.forward.length > a) {
z.extra += 1
a = z.forward.length
} else if (update[0].forward[0].forward[z.forward.length - 1] == z) {
if (update[0].forward[0].forward[0] == z) {
z.extra = 0
} else if (x.forward.length == z.forward.length) {
z.extra -= x.extra
} else if (update[z.forward.length - 1] != update[0]){
z.extra = z.extra - x.extra + 1
}
}
}
z = z.forward[0]
}
this.NIL.extra += 1
}
}
Search(key) {
let x = this.header;
for (let i = this.level - 1; i >= 0; i--) {
while (x.forward[i].key < key) {
x = x.forward[i];
}
}
x = x.forward[0];
if (x.key == key) {
return x.val;
} else {
return undefined;
}
}
Delete(key) {
let update = newArray(this.maxLevel, this.update);
let x = this.header;
for (let i = this.level - 1; i >= 0; i--) {
while (x.forward[i].key < key) {
x = x.forward[i];
}
update[i] = x;
}
x = x.forward[0];
if (x.key === key) {
for (let i = 0; i < this.level; i++) {
if (update[i].forward[i] != x) {
break;
} else {
update[i].forward[i] = x.forward[i];
}
}
while (
this.level > 1 &&
this.header.forward[this.level - 2] === this.NIL
) {
this.level--;
}
let a = x.forward.length
let z = update[0].forward[0]
while (z.key != Infinity) {
if (z.forward.length > a) {
z.extra -= 1
a = z.forward.length
} else if (x.forward.length == z.forward.length) {
z.extra += x.extra
} else if (x.forward.length > z.forward.length) {
if (update[z.forward.length - 1] != update[0]) {
z.extra += x.extra
}
}
z = z.forward[0]
}
this.NIL.extra -= 1
} else {
throw `Key Error: key '${key}' not found.`;
}
}
Order(key) {
let total = 0;
let x = this.header;
for (let i = this.level - 1; i >= 0; i--) {
while (x.forward[i].key < key) {
x = x.forward[i];
total += x.extra + 1;
}
}
return total;
}
toString() {
let s = "header";
let x = this.header;
while (x.forward[0] != this.NIL) {
x = x.forward[0];
s = s + ` -> [${x.key}|${x.val}]`;
}
return s + " -> NIL";
}
randomLevel() {
let level = 1;
while (Math.random() < this.p && level < this.maxLevel - 1) {
level++;
}
return level;
}
}