欢迎阁下光临我的github前端知识汇总 https://github.com/JimmyLLLL/js 如果您可以慷慨赠予我星星,在下不胜感激!
百度百科:二叉搜索树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
二叉搜索树个人解读:比它小放左边,比它大放右边
class Node{
constructor(value){
this.value = value
this.left = null
this.right = null
}
}
//插入节点函数的辅助函数,用来递归,递归的内容对初学者来讲有点难,但是相信我,时间可以消磨一切,一遍又一遍,你可以看懂的!我也在此陪你,加油~
function insertNodeHelper(node,newNode){
if(node.value < newNode.value){
if(node.right===null){
node.right = newNode
}else{
insertNodeHelper(node.right,newNode)
}
}else{
if(node.left===null){
node.left = newNode
}else{
insertNodeHelper(node.left,newNode)
}
}
}
//插入节点函数,看似没有存在的意义,但是可以避免函数本身递归化,也可以在函数里面加一些定制内容
function insertNode(root,newNode){
insertNodeHelper(root,newNode)
}
//前序遍历
function preOrder(root){
if(root){
console.log(root.value) //这个console.log功能是你定制的,这个定制功能我们现在定义为console.log,放前面就叫做前序遍历
//这个遍历对初学者来讲注定复杂,但是请想象函数执行是一个调用栈,开始执行就是压栈,执行完毕就出栈。点到即止,希望读者好好思考,加油!
preOrder(root.left)
preOrder(root.right)
}
}
function inOrder(root){
if(root){
inOrder(root.left)
console.log(root.value)
inOrder(root.right)
}
}
function postOrder(root){
if(root){
postOrder(root.left)
postOrder(root.right)
console.log(root.value)
}
}
function removeNode(root,value,father=null,diretion=''){
if(root.value < value){
//如果你要删除的值比根大,那么去根的右边找吧
removeNode(root.right,value,root,'right')
}else if(root.value > value){
removeNode(root.left,value,root,'left')
}else{
//找到后...
if(root.right){
//如果删除的目标节点右边有值,右边这个值要接替这个被删除的位置,假如删除节点的左边有值,那么就要归于删除节点的右边节点的门下
root.left && insertNode(root.right,root.left)
//被删除节点的父节点的指向子的指针也要从此指向被删除节点的右边
father && (father[diretion] = root.right)
}else{
//如果没有右节点,那就只能把被删除节点的左边节点放在被删除节点的父节点门下了,如果连左节点都没有,那么被删除节点的父节点指向子节点的指针就要设为空了
root.left ? father && (father[diretion] = root.left) : father && (father[diretion] = null)
}
root = null //这个只是心理安慰而已,参数的指针是复制来的,不能使得原来的内存区域被释放,要想原来被删除的节点的内存被释放,还是要找回原来定义这个节点的变量,赋值null
}
}