数据结构笔记_25 二叉树删除结点

本节任务:

  1. 如果删除的节点是叶子节点,则删除该节点
  2. 如果删除的节点是非叶子节点,则删除该子树
  3. 测试删除5号叶子节点和3号子树

思路图解:

在这里插入图片描述

规定:

  1. 如果删除的节点是叶子节点,则删除该节点。
  2. 如果删除的节点是非叶子节点,则删除该子树。

把判断root的逻辑写在BinaryTree二叉树的删除方法里,然后递归的逻辑写在HeroNode节点的删除方法里。

思路:

首先处理:

考虑如果树是空树,和如果只有一个root节点,则等价于将二叉树置空。

	public void delNode(int no) {
    
    
		if (root != null) {
    
    
			// 如果只有一个root结点,这里立即判断root是不是要删除的结点
			if (root.getNo() == no) {
    
    
				root = null;
			} else {
    
    
				// 递归删除
				root.delNode(no);
			}
		} else {
    
    
			System.out.println("空树,不能删除~");
		}
	}

然后进行下面的步骤:

  1. 因为我们的二叉树是单向的,所以我们是判断当前结点的子结点是否需要删除,而不能去判断当前这个结点是不是需要删除的
  2. 如果当前结点的左子结点不为空,并且左子结点就是要删除结点,就将this.left=null;并且就返回(结束递归删除)
  3. 如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将this. right=null;并且就返回(结束递归删除)
  4. 如果第2和第3步没有删除结点,那么我们就需要向左子树进行递归删除
  5. 如果第4步也没有删除结点,则应当向右子树进行递归删除
	public void delNode(int no) {
    
    
		// 2.如果当前结点的左子结点不为空,并且左子结点就是要删除结点,就将this.left=null;并且就返回(结束递归删除)
		if (this.left != null && this.left.no == no) {
    
    
			this.left = null;
			return;
		}
		// 3.如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将this. right=null;并且就返回(结束递归删除)
		if (this.right != null && this.right.no == no) {
    
    
			this.right = null;
			return;
		}
		// 4.如果第2和第3步没有删除结点,那么我们就需要向左子树进行递归删除
		if (this.left != null) {
    
    
			this.left.delNode(no);
			// 这里先不要写return 防止左子树没有删除成功,需要进入右子树的递归删除
		}
		// 5.如果第4步也没有删除结点,则应当向右子树进行递归删除
		if (this.right != null) {
    
    
			this.right.delNode(no);
		}
	}

测试:
在这里插入图片描述
流程(以删除5号节点为例):

首先,在树类中,判断根节点不是空的,并且根节点的编号1不是需要删除的,所以进入HeroNode里的递归删除。

其次,进入节点类中的删除方法。进入一个判断:根节点的左子节点不为空,且左子节点的编号2不是要找的编号5,退出本次判断。

进入下一个判断:根节点的右子节点不为空,且右子节点的编号3不是要找到编号,退出本次判断。

进入下一个判断,上面两个操作都没有删除节点,且2号(根节点的左子节点)不为空,于是进入其左递归删除。进入递归后,判断2号的左子节点为空,又判断2号的右子节点为空。所以本次递归,四个判断条件一个都没满足,退出根节点左子树的递归删除。

进入根节点右子树的递归删除。先判断其左子节点不为空 且 左子节点的编号5就是要删除的节点编号5,直接删除(置空)该节点后,return.
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45909299/article/details/114207259