有了前文对BST的前驱后驱理解的基础,还不理解的小伙伴戳这里二叉搜索树的前驱、后驱.我们便可以学习BST的插入和删除操作
插入节点:
需要从根结点开始查找待插入节点位置,找到位置后插入即可,如若在查找过程碰到相同元素 插入失败
代码如下:
// 二叉搜索树插入节点
public static boolean insert(TreeNode root, TreeNode node) {
TreeNode tree = root;
TreeNode p = null;
// 寻找合适的插入位子 p节点即为插入节点的父节点
while (tree != null) {
p = tree;
if (tree.val > node.val) { // 小于比较节点 放入比较节点的左子树
tree = tree.left;
} else if (tree.val < node.val) { // 大于比较节点 放入比较节点的右子树
tree = tree.right;
} else {
return false; // 二叉搜索树中已有相同元素节点 插入失败
}
}
node.parent = p;
if (p == null) { // root 为null node为根节点
root = node;
} else if (p.val > node.val) {
p.left = node;
} else {
p.right = node;
}
return true;
}
删除节点
删除节点可以分以下3个情形:
1.待删除节点没有左,右孩子(即为叶子节点),直接删除
2.待删除节点只有1个子节点,将待删除节点的父节点设置为该子节点的父节点,
3.待删除节点有2个子节点,可以通过寻找待删除节点的后驱节点,来转化为以上2种情况,具体操作如下
这时我们并不直接删除待删除节点,而是删除待删节点的后驱节点,找到后驱节点后,将待删除节点的父节点设置为后驱节点子节点的父节点,同时将后驱节点的val设置到待删节点上,此时便完成删除操作
如下图:
![](https://img.haomeiwen.com/i12869053/6fb1e24e873592ef.png)
Java代码实现如下:
// 二叉搜索树删除节点
public static void delete(TreeNode root, TreeNode node) {
TreeNode deleteNode = null;
if (node.left == null || node.right == null) {
deleteNode = node;
} else {
// 后驱节点即为删除节点 (后驱节点 必然没有左子节点)
deleteNode = postNode(node);
}
// 删除节点必然不会超过一个子节点 要么1个 要么没有子节点
TreeNode child = deleteNode.left == null ? deleteNode.right : deleteNode.left;
if (child != null) {
child.parent = deleteNode.parent;
}
if (deleteNode.parent == null) // 待删除节点没有父节点删除为节点后子孩子就是根节点了
root = child;
else if (deleteNode == deleteNode.parent.left) {
deleteNode.parent.left = child;
} else
deleteNode.parent.right = child;
// 如果删除节点是后驱节点 则需把删除的后驱节点的值设置在node上
if (node != deleteNode) {
node.val = deleteNode.val;
}
}
网友评论