Skip to content

Instantly share code, notes, and snippets.

@rezaerami
Last active June 20, 2021 13:55
Show Gist options
  • Save rezaerami/3c7a4a3f665159369fbfc49cd6a2b790 to your computer and use it in GitHub Desktop.
Save rezaerami/3c7a4a3f665159369fbfc49cd6a2b790 to your computer and use it in GitHub Desktop.
here is an implementation of Cartesian tree in Javascript
/**
* Creates a Node with value, lett and right children properties
* @param value
* @constructor
*/
function Node(value){
this.value = value;
this.right = undefined;
this.left = undefined;
}
/**
* Creates a tree on construct and returns the spine and the tree itself as the result
* @param spine
* @constructor
*/
function CartesianTree(spine){
/**
* makes spine local to use in protorypes
*/
this.spine = spine;
this.result = (function generateTree(start, end){
/**
* checks if start and end of the range is valid
*/
if(start > end){
return undefined;
}
/**
* slices the range from the spine to search min value in
*/
const slicedRange = spine.slice(start, end);
if(!slicedRange.length){
return undefined;
}
/**
* gets the min value and it's index in range
*/
const minValue = Math.min(...slicedRange);
const minValueIndex = spine.indexOf(minValue);
/**
* creates an instance of node with given value
* @type {Node}
*/
const current = new Node(minValue)
/**
* navigates through the spine for values before this node to find the smallest one
*/
current.left = generateTree(start, minValueIndex);
/**
* navigates through the spine for values after this node to find the smallest one
*/
current.right = generateTree(minValueIndex + 1, end);
return current;
})(0)
}
CartesianTree.prototype.search = function(value){
/**
* make spine local in the prototype to use it in inner function to access it without binding
*/
const spine = this.spine;
/**
* creates an inner function which is immediately invoked to avoid passing the current branch to outer function
*/
return (function search(branch, value){
/**
* gets the index of the current branch and puts it into a variable called parent,
* cause we're gonna go deeper
*/
const parentIndex = spine.indexOf(branch.value);
/**
* gets the index of the given value in spine
*/
const valueIndex = spine.indexOf(value);
/**
* checks if value and parent index are the same,
* it means they are both one element so the current branch will be the result of the search
*/
if(parentIndex === valueIndex){
return branch;
}
/**
* since the smaller values are always in the left hand of the branch,
* if the index of the value is less than the index of theparent,
* it should take the left side to navigate through
* otherwise it should take the right branches
*/
if(parentIndex > valueIndex){
return search(branch.left, value);
}
else {
return search(branch.right, value);
}
})(this.result, value)
}
const spine = [9, 3, 7, 1, 8, 12, 10, 20, 15, 18, 5];
const cartesianTree = new CartesianTree(spine);
console.log(cartesianTree);
console.log(cartesianTree.search(10));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment