Last active
June 20, 2021 13:55
-
-
Save rezaerami/3c7a4a3f665159369fbfc49cd6a2b790 to your computer and use it in GitHub Desktop.
here is an implementation of Cartesian tree in Javascript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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