class Treap {
constructor (node = null) {
this.node = node
}
insert (key) {
this.assistInsertion(key,Math.random())
}
turnRight () {
let [d, b, C] = [this.node, this.node.left.node, this.node.left.node.right.node];
[this.node, b.right.node, d.left.node] = [b, d, C];
}
remove (key, tree = true) {
const valid = tree === true ? this : tree;
if (!valid.node) throw 'Key not in the tree';
if (valid.node.key > key) valid.node.left = this.remove(key, valid.node.left);
if (valid.node.key < key) valid.node.right = this.remove(key, valid.node.right);
if (!valid.node.right.node && !valid.node.left.node) valid.node = null;
if (valid.node.right.node && valid.node.left.node) {
if (valid.node.left.node.priority > valid.node.right.node.priority) {
valid.node = this.turnLeft(valid.node);
valid.node.left = this.remove(key, valid.node.left);
}
else {
valid.node = this.turnRight(valid.node);
valid.node.right = this.remove(key, valid.node.right);
}
}
else valid.node = (valid.node.left.node) ? valid.node.left.node : valid.node.right.node;
return valid;
}
turnLeft () {
let [b, d, C] = [this.node, this.node.right.node, this.node.right.node.left.node];
[this.node, d.left.node, b.right.node] = [d, b, C];
}
assistInsertion (key,priority) {
if (!this.node)
this.node = new TreapNode(key, priority,new Treap(), new Treap())
else if (this.node.key == key)
throw ("key already exists")
else if (this.node.key < key){
if (!this.node.right.node)
this.node.right.node = new TreapNode(key, priority,new Treap(), new Treap())
else if (this.node.right.node.priority < priority || !this.node.right.node )
this.node.right.weighInsertion(key, priority)
else
this.node.right.assistInsertion(key, priority)
}
else if (this.node.key > key){
if (!this.node.left.node)
this.node.left.node = new TreapNode(key, priority,new Treap(), new Treap())
else if (this.node.left.node.priority < priority || !this.node.right.node )
this.node.left.weighInsertion(key, priority)
else
this.node.left.assistInsertion(key, priority)
}
}
weighInsertion (key, priority) {
if (!this.node)
this.node = new TreapNode(key, priority,new Treap(), new Treap())
else if (this.node.key == key)
throw ("key already exists")
else if (this.node.key < key){
this.node.right.weighInsertion(key, priority)
this.turnLeft()
}
else if (this.node.key > key){
this.node.left.weighInsertion(key, priority)
this.turnRight()
}
}
}