class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
insert(data) {
if (data < this.data && this.left) {
this.left.insert(data);
} else if (data < this.data) {
this.left = new Node(data);
} else if (data > this.data && this.right) {
this.right.insert(data);
} else if (data > this.data) {
this.right = new Node(data);
}
}
}
// to be valid, node should satisfy min and max ALONGSIDE with all his children
// first we check if node data satisfying min and max
// then we do recursive check for node left and right children
function validate(node, min = null, max = null) {
const { left, right, data } = node;
// node is invalid when doesn't satisfy min or max
if ((max && data > max) || (min && data < min)) return false;
// true by default, since if node doesn't have a child, it should be accepted as valid
let isLeftChildValid = true;
let isRightChildValid = true;
if (left) isLeftChildValid = validate(left, min, data);
if (right) isRightChildValid = validate(right, data, max);
// at this step node validity depends on validity of his children
// because all check of node data itself was made above (line 8)
return isLeftChildValid && isRightChildValid;
}
// --- Directions
// Create an 'eventing' library out of the
// Events class. The Events class should
// have methods 'on', 'trigger', and 'off'.
class Events {
constructor() {
this.event = {}
}
// Register an event handler
on(eventName, callback) {
if (this.event.hasOwnProperty(eventName)) {
this.event[eventName].push(callback);
} else {
this.event[eventName] = [callback];
}
}
// Trigger all callbacks associated
// with a given eventName
trigger(eventName) {
if (!this.event.hasOwnProperty(eventName)) return;
for (let cb of this.event[eventName]) {
cb();
}
}
// Remove all event handlers associated
// with the given eventName
off(eventName) {
delete this.event[eventName];
}
}