02_二叉搜索树_删除任意一个节点

删除一个节点

前面博客只写到添加节点,接下来利用上一篇的博客前驱与后继,写下删除节点

删除主要包括

  • 删除的节点度为0
  • 删除的节点度为1
  • 删除的节点度为2

1.叶子节点:直接删除

在这里插入图片描述

2.度为1的节点:用子节点替代删除的节点

在这里插入图片描述

3.度为2的节点:用前驱或后继节点取代删除的节点,然后删除这个前驱或后继的节点

  • 如果一个节点的度为2,那么它的前驱或者后继节点的度只能为0或1
    在这里插入图片描述

4.代码描述

  • 1.度为2的节点,删除前驱或后继,即找到那个节点更新删除的节点node为前驱或后继即可
  • 2.传入参数是需要删除的节点元素,需要封装通过元素返回节点对象的方法
/**
 * 1.如果node.left != null || node.right != null,说明 node 是度为1的节点
 * 		1.1需要更新孩子节点的父节点parent为删除节点的父节点
 * 			用replacement保存是左节点还是右节点  node.left != null ? node.left : node.right;
 * 		1.2父节点为空,说明为根节点,更新root为replacement
 * 		1.3父节点不为空,判断需要删除的节点node为左子树还是右子树
 * 			1.3.1需要删除的节点为其父节点的左子树,则其父节点的左子树置为删除节点的孩子节点replacement node == node.parent.left
 * 			1.3.2需要删除的节点为其父节点的右子树,则其父节点的右子树置为删除节点的孩子节点replacement node == node.parent.right
 * 2.否则说明 node 是度为0的节点
 * 		2.1为根节点,则root置为空
 * 		2.2为叶子节点,判断是左还是右
 * 			2.2.1需要删除的节点为为其父节点的左子树,则其父节点的左子树置为空 node == node.parent.left
 * 			2.2.2需要删除的节点为为其父节点的右子树,则其父节点的右子树置为空 node == node.parent.right
*/
	public void remove(E element) {
		remove(node(element));
	}

	private Node<E> node(E element) {
		Node<E> node = root;
		while (node != null) {
			int cmp = compare(element, node.element);
			if (cmp == 0) return node;
			if (cmp > 0) {
				node = node.right;
			} else { // cmp < 0
				node = node.left;
			}
		}
		return null;
	}

	private void removeMy(Node<E> node){
		if(node == null)
			return;

		size--;
		
		// 度为2的节点
		if(node.hasTwoChildren()){
			// 找到后继节点
			Node<E> s = successor(node);
			// 用后继节点的值覆盖度为2的节点的值
			node.element = s.element;
			// 删除后继节点
			node = s;
		}
		
		// 度为1的节点
		if(node.left != null || node.right != null){

			Node<E> replacement = node.left != null ? node.left : node.right;

			replacement.parent = node.parent;

			if(node.parent == null){
				root = replacement;
			} else if (node == node.parent.left){
				node.parent.left = replacement;
			} else if (node == node.parent.right){
				node.parent.right = replacement;
			}
		} else { //度为0的节点
			if (node.parent == null){
				root = null;
			} else if (node == node.parent.left){
				node.parent.left = null;
			} else if (node == node.parent.right){
				node.parent.right = null;
			}
		}
	}
	总结:度为0的时候,删除节点需要考虑删除的节点是否为根节点,
	      度为1的时候,删除节点需要考虑删除的节点的父节点是否为根节点,
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值