二叉搜索树删除算法(非递归写法)
删除结点分4中情况:
- 无左右子节点,直接删除
- 有左子节点、无右子节点,将左子节点替换到删除结点处
- 有右子节点、无左子节点,将右子节点替换到删除结点处
- 有左有右, 选左子树最右结点 或 右子树最左结点替换
function deleteNode(root, key) {
if(root === null ) return root
let cur = root , pre = new TreeNode('a') ,sign = 'l'
pre.left = root
while(cur){
if(cur.val === key) break
else if(cur.val > key){
if(cur.left) {pre = cur ;sign = 'l'; cur = cur.left}
else return root
}
else{
if(cur.right) {pre = cur ; sign = 'r'; cur = cur.right}
else return root
}
}
if(!(cur.left || cur.right)){
// 无左 无右,直接删除
sign === 'l' ? pre.left = null : pre.right = null
return cur.val === root.val ? pre.left : root
}
if( cur.left && !cur.right){
// 有左 无右,左节点顶上来
sign === 'l' ? pre.left = cur.left : pre.right = cur.left
return cur.val === root.val ? pre.left : root
}
if(!cur.left && cur.right ){
// 无左 有右, 右节点顶上来
sign === 'l' ? pre.left = cur.right : pre.right = cur.right
return cur.val === root.val ? pre.left : root
}
if( cur.left && cur.right ){
// 有左有右, 选左子树最右结点 或 右子树最左结点替换
var tempPre = cur ,tsign = 'r'
var leftest = cur.right
while(leftest.left){
// 找到最左
tempPre = leftest
tsign = 'l'
leftest = leftest.left
}
if(leftest.right) {
tsign === 'l' ? tempPre.left = leftest.right : tempPre.right = leftest.right
}else tsign === 'l' ? tempPre.left = null : tempPre.right = null
leftest.left = cur.left
leftest.right = cur.right
sign === 'l' ? pre.left = leftest : pre.right = leftest
return cur.val === root.val ? pre.left : root
}
};