class Node {
constructor(val) {
this.val = val;
this.left = null;
this.right = null;
}
}
class BST {
constructor() {
this.root = null;
}
insert(val) {
const newNode = new Node(val);
if (!this.root) {
this.root = newNode;
return;
}
let curr = this.root;
while (true) {
if (val < curr.val) {
if (!curr.left) {
curr.left = newNode;
return;
}
curr = curr.left;
} else {
if (!curr.right) {
curr.right = newNode;
return;
}
curr = curr.right;
}
}
}
floorCeil(target) {
let floor = null;
let ceil = null;
let curr = this.root;
while (curr) {
if (curr.val === target) {
floor = curr.val;
ceil = curr.val;
break;
} else if (target < curr.val) {
ceil = curr.val; // update ceil candidate
curr = curr.left; // go left to find smaller or equal
} else {
floor = curr.val; // update floor candidate
curr = curr.right; // go right to find bigger or equal
}
}
return { floor, ceil };
}
}
// Driver code
const bst = new BST();
[8,4,12,2,6,10,14].forEach(v => bst.insert(v));
const target = 5;
const { floor, ceil } = bst.floorCeil(target);
console.log(`Floor: ${floor}`);
console.log(`Ceil: ${ceil}`);loop to traverse nodes until no more candidates
if (curr.val === target) {
exact match found, floor and ceil are target
else if (target < curr.val) {
target less than current, update ceil and go left
ceil = curr.val; // update ceil candidate
record current node as possible ceil
curr = curr.left; // go left to find smaller or equal
move left to find closer ceil or floor
target greater than current, update floor and go right
floor = curr.val; // update floor candidate
record current node as possible floor
curr = curr.right; // go right to find bigger or equal
move right to find closer floor or ceil