二叉树删除指定节点

二叉树删除节点:

1.要求:

  • 如果删除的节点是叶子结点,则删除该结点。
  • 如果删除的节点是非叶子结点,则删除该子树。

2.思路:

  • 首先处理根节点:判断树是否为空,如果只有一个结点,判断此结点是不是要删除的结点。
  • 因为二叉树是单向所以我们判断当前子结点是否需要删除结点,而不能去判断当前这个结点是不是需要删除的节点。
  • 如果当前结点的左子结点不为空,并且左子结点就是要删除的结点就将this.left = null;并返回(结束递归删除)
  • 如果当前结点的右子结点不为空,并且右子结点就是要删除的结点,就将this.right = null;并返回(结束递归删除)
  • 如果上面步骤没有删除那么就需要向左右子树进行递归删除。

3.代码演示:

在这里插入图片描述

(1)、主方法:


public class binaryTreeDemo {
    
    
	public static void main(String[] args) {
    
    
	//先创建一个二叉树
		BinaryTree binaryTree = new BinaryTree();
	//创建需要的结点
		HeroNode root = new HeroNode(1,"1");
		HeroNode node2 = new HeroNode(2,"2");
		HeroNode node3 = new HeroNode(3,"3");
		HeroNode node4 = new HeroNode(4,"4");
		HeroNode node5 = new HeroNode(5,"5");
		
	//说明:手动创建二叉树
		root.setLeft(node2);
		root.setRight(node3);
		node3.setLeft(node5);
		node3.setRight(node4);
	//测试:
		binaryTree.setRoot(root);
		System.out.println("删除前,前序遍历");
		binaryTree.centerOrder();
		binaryTree.del(5);
		System.out.println("删除后,前序遍历");
		binaryTree.centerOrder();
	}
}

(2)、定义一个二叉树:

//定义一个二叉树
class binaryTree{
    
    
	//根节点
	private Node root;
	//一个set方法
	public void setRoot(Node root) {
    
    
		this.root = root;
	}
	
	//删除结点
	public void del(int no){
    
    
		if(this.root!=null){
    
    
			//是否只有一个结点,这里立即判断root是不是就是要删除结点
			if(root.getNo() == no) {
    
    
				root = null;
			}else {
    
    
				//递归删除
				root.delNode(no);
			}
		}else{
    
    
			System.out.println("空树不能删除");
		}
	}

	//前序遍历
	public void preOrder() {
    
    
		if(this.root != null) {
    
    
			this.root.preOrder();
		}else {
    
    
			System.out.println("二叉树为空,无法遍历");
		}
	}
	
}

(3)、创建结点:

//创建结点
class Node{
    
    
	private int no;
	private String name;
	private HeroNode left;//默认null
	private HeroNode right;//默认null
	public HeroNode(int no,String name) {
    
    
		this.no = no;
		this.name = name;
	}
	public int getNo() {
    
    
		return no;
	}
	public void setNo(int no) {
    
    
		this.no = no;
	}
	public String getName() {
    
    
		return name;
	}
	public void setName(String name) {
    
    
		this.name = name;
	}
	public HeroNode getLeft() {
    
    
		return left;
	}
	public void setLeft(HeroNode left) {
    
    
		this.left = left;
	}
	public HeroNode getRight() {
    
    
		return right;
	}
	public void setRight(HeroNode right) {
    
    
		this.right = right;
	}
	@Override
	public String toString() {
    
    
		return "HeroNode [no=" + no + ", name=" + name + "]";
	}

	//递归删除节点
	//1、如果删除的结点是叶子结点,则删除该结点
	//2、如果删除的结点是非叶子结点,则删除该子树
	public void delNode(int no){
    
    
		//判断当前结点的左子结点是否为空且是否是要删除的结点
		if(this.left!=null && this.left.no==no){
    
    
			this.left = null;
			return;
		}
		//判断当前结点的右子结点是否为空且是否是要删除的结点
		if(this.right!=null && this.right.no==no){
    
    
			this.right = null;
			return;
		}
		//向左子树进行递归删除
		if(this.left!=null) {
    
    
			this.left.delNode(no);
		}
		//向右子树进行递归删除
		if(this.right!=null) {
    
    
			this.right.delNode(no);
		}
	}

	//编写前序遍历的方法
	public void preOrder() {
    
    
		System.out.println(this);//先输出父结点
		//递归向左子树前序
		if(this.left != null) {
    
    
			this.left.preOrder();
		}
		//递归向右子树前序遍历
		if(this.right != null) {
    
    
			this.right.preOrder();
		}
	}

}

代码分析:

del方法: 以当前根结点1为例首先进入del方法中判断当前结点是否为空和是否是要查找的结点,如果不是则进入delNode方法中。

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

delNode方法:

public void delNode(int no) {
    
    
		//如果当前结点的左子结点不为空,并且左子结点就是要删除的结点,就将this.left = null,并且就返回(结束递归删除)
		if(this.left!=null && this.left.no == no) {
    
    
			this.left = null;
			return;
		}
		//如果当前结点的右子结点不为空,并且右子结点就是要删除的结点,就将this.right = null,并且就返回(结束递归删除)
		if(this.right!=null && this.right.no == no) {
    
    
			this.right = null;
			return;
		}
		
		//向左子树进行递归删除
		if(this.left!=null) {
    
    
			this.left.delNode(no);
		}
		//向右子树进行递归删除
		if(this.right!=null) {
    
    
			this.right.delNode(no);
		}
		
	}
  1. 此时this.left指的是2,但是此结点不是我们要查找的结点。
  2. 接着进行右结点判断,此时this.right指的是3不是我们要查找的结点。
  3. 回到root结点(归),向左子树进行递归删除,此时左结点为2不为空进入delNode函数(递),this.left为空、this.right为空,向左子树尝试递归删除失败、向右子树尝试递归删除失败,则回到1号结点(归)。
  4. 向右子树进行递归删除,此时左结点this.left不为空并且是我们要查找的数5,此时就会将3号的左边置空。
  5. 此时代码回到binaryTree里面的else
  6. 回到主方法结束。

猜你喜欢

转载自blog.csdn.net/weixin_43690348/article/details/110587591
今日推荐