热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

二叉树的删除内含全部代码

二叉树-删除节点要求如果删除的节点是叶子节点,则删除该节点如果删除的节点是非叶子节点,则删除该子树.测试,删除掉5号叶子节点和3号子树.完
二叉树-删除节点

要求

  1. 如果删除的节点是叶子节点,则删除该节点
  2. 如果删除的节点是非叶子节点,则删除该子树.
  3. 测试,删除掉 5 号叶子节点 和 3 号子树.
  4. 完成删除思路分析
    在这里插入图片描述


代码实现

package com.iflytek.tree;//先创建HeroNode 结点
class HeroNode {private int no;private String name;private HeroNode left;//默认 nullprivate HeroNode right;//默认 nullpublic 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;}@Overridepublic String toString() {return "HeroNode{" +"no=" + no +", name='" + name + '\'' +'}';}//编写前序遍历的方法public void preOrder() {System.out.println(this);//先输出父结点//递归向左子树前序遍历if (this.left != null) {this.left.preOrder();}//递归向右子树前序遍历if (this.right != null) {this.right.preOrder();}}//中序遍历public void infixOrder() {//递归向左子树中序遍历if (this.left != null) {this.left.infixOrder();}//输出父结点System.out.println(this);//递归向右子树中序遍历if (this.right != null) {this.right.infixOrder();}}//后序遍历public void postOrder() {//递归向左子树中序遍历if (this.left != null) {this.left.postOrder();}//递归向右子树中序遍历if (this.right != null) {this.right.postOrder();}//输出父结点System.out.println(this);}/*** 前序遍历查找** @param no 查找 no* @return 如果找到就返回该Node ,如果没有找到返回 null*/public HeroNode preOrderSearch(int no) {System.out.println("进入前序遍历");//比较当前结点是不是if (this.no == no) {return this;}//1.则判断当前结点的左子节点是否为空,如果不为空,则递归前序查找//2.如果左递归前序查找,找到结点,则返回HeroNode resNode = null;if (this.left != null) {resNode = this.left.preOrderSearch(no);}if (resNode != null) {//说明我们左子树找到return resNode;}//1.左递归前序查找,找到结点,则返回,否继续判断,//2.当前的结点的右子节点是否为空,如果不空,则继续向右递归前序查找if (this.right != null) {resNode = this.right.preOrderSearch(no);//不需要在判断的,直接返回}return resNode;}/*** 中序遍历查找** @param no 查找 no* @return 如果找到就返回该Node ,如果没有找到返回 null*/public HeroNode infixOrderSearch(int no) {//判断当前结点的左子节点是否为空,如果不为空,则递归中序查找HeroNode resNode = null;if (this.left != null) {resNode = this.left.infixOrderSearch(no);}if (resNode != null) {return resNode;}System.out.println("进入中序查找");//如果找到,则返回,如果没有找到,就和当前结点比较,如果是则返回当前结点if (this.no == no) {return this;}//否则继续进行右递归的中序查找if (this.right != null) {resNode = this.right.infixOrderSearch(no);}return resNode;}/*** 后序遍历查找** @param no 查找 no* @return 如果找到就返回该Node ,如果没有找到返回 null*/public HeroNode postOrderSearch(int no) {//判断当前结点的左子节点是否为空,如果不为空,则递归后序查找HeroNode resNode = null;if (this.left != null) {resNode = this.left.postOrderSearch(no);}if (resNode != null) {//说明在左子树找到return resNode;}//如果左子树没有找到,则向右子树递归进行后序遍历查找if (this.right != null) {resNode = this.right.postOrderSearch(no);}if (resNode != null) {return resNode;}System.out.println("进入后序查找");//如果左右子树都没有找到,就比较当前结点是不是if (this.no == no) {return this;}return resNode;}//1.如果删除的节点是叶子节点,则删除该节点//2.如果删除的节点是非叶子节点,则删除该子树/*** 分析:思路* 1. 因为我们的二叉树是单向的,所以我们是判断当前结点的子结点是否需要删除结点,* 而不能去判断 当前这个结点是不是需要删除结点.* 2. 如果当前结点的左子结点不为空,并且左子结点就是要删除结点,就将 this.left = null;* 并且就返回(结束递归删除)* 3. 如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将 this.right= null ;* 并且就返回(结束递归删除)* 4. 如果第 2 和第 3 步没有删除结点,那么我们就需要向左子树进行递归删除* 5. 如果第 4 步也没有删除结点,则应当向右子树进行递归删除.*/public void delNode(int no) {if (this.left != null && this.left.no == no) {this.left = null;return;}if (this.right != null && this.left.no == no) {this.right = null;return;}if (this.left != null) {this.left.delNode(no);}if (this.right != null) {this.right.delNode(no);}}}class BinaryTree {private HeroNode root;public void setRoot(HeroNode root) {this.root = root;}//前序遍历public void preOrder() {if (this.root != null) {this.root.preOrder();} else {System.out.println("二叉树为空,无法遍历");}}//中序遍历public void infixOrder() {if (this.root != null) {this.root.infixOrder();} else {System.out.println("二叉树为空,无法遍历");}}//后序遍历public void postOrder() {if (this.root != null) {this.root.postOrder();} else {System.out.println("二叉树为空,无法遍历");}}//前序查找public HeroNode preOrderSearch(int no) {if (this.root != null) {return this.root.preOrderSearch(no);} else {return null;}}//中序查找public HeroNode infixOrderSearch(int no) {if (this.root != null) {return this.root.infixOrderSearch(no);} else {return null;}}//后序查找public HeroNode postOrderSearch(int no) {if (this.root != null) {return this.root.postOrderSearch(no);} else {return null;}}//删除结点public void delNode(int no) {if (root != null) {//如果只有一个 root 结点, 这里立即判断 root 是不是就是要删除结点if (root.getNo() == no) {root = null;} else {//递归删除root.delNode(no);}} else {System.out.println("空树,不能删除");}}}public class BinaryTreeDemo {public static void main(String[] args) {//先需要创建一颗二叉树BinaryTree binaryTree = new BinaryTree();//创建需要的结点HeroNode root = new HeroNode(1, "宋江");HeroNode node2 = new HeroNode(2, "吴用");HeroNode node3 = new HeroNode(3, "卢俊义");HeroNode node4 = new HeroNode(4, "林冲");HeroNode node5 = new HeroNode(5, "关胜");//说明,我们先手动创建该二叉树,后面我们学习递归的方式创建二叉树root.setLeft(node2);root.setRight(node3);node3.setRight(node4);node3.setLeft(node5);binaryTree.setRoot(root);/* //测试System.out.println("前序遍历"); // 1,2,3,5,4binaryTree.preOrder();//测试System.out.println("中序遍历");binaryTree.infixOrder(); // 2,1,5,3,4//测试System.out.println("后序遍历");binaryTree.postOrder(); // 2,5,4,3,1*//* HeroNode resNode=null;//前序遍历查找//前序遍历的次数 :4System.out.println("前序遍历方式~~~");resNode = binaryTree.preOrderSearch(5);if (resNode!=null){System.out.printf("找到了,信息为 no=%d name=%s\n", resNode.getNo(), resNode.getName());}else {System.out.printf("没有找到 no = %d 的英雄",5);}//中序遍历查找//中序遍历 3 次System.out.println("中序遍历方式~~~");resNode = binaryTree.infixOrderSearch(5);if (resNode!=null){System.out.printf("找到了,信息为 no=%d name=%s\n", resNode.getNo(), resNode.getName());}else {System.out.printf("没有找到 no = %d 的英雄", 5);}//后序遍历查找//后序遍历查找的次数 2 次System.out.println("后序遍历方式~~~");resNode = binaryTree.postOrderSearch(5);if (resNode!=null){System.out.printf("找到了,信息为 no=%d name=%s\n", resNode.getNo(), resNode.getName());}else {System.out.printf("没有找到 no = %d 的英雄", 5);}*/System.out.println("删除前,前序遍历");binaryTree.preOrder(); // 1,2,3,5,4binaryTree.delNode(5);//binaryTree.delNode(3);System.out.println("删除后,前序遍历");binaryTree.preOrder(); // 1,2,3,4}
}

思考题(课后练习)


  1. 如果要删除的节点是非叶子节点,现在我们不希望将该非叶子节点为根节点的子树删除,需要指定规则, 假如 规定如下:
  2. 如果该非叶子节点A只有一个子节点 B,则子节点 B替代节点A
  3. 如果该非叶子节点A有左子节点 B 和右子节点 C,则让左子节点 B 替代节点A。
  4. 请大家思考,如何完成该删除功能, (课后练习)
  5. 后面在讲解 二叉排序树时,在给大家讲解具体的删除方法
    在这里插入图片描述

推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 面向对象之3:封装的总结及实现方法
    本文总结了面向对象中封装的概念和好处,以及在Java中如何实现封装。封装是将过程和数据用一个外壳隐藏起来,只能通过提供的接口进行访问。适当的封装可以提高程序的理解性和维护性,增强程序的安全性。在Java中,封装可以通过将属性私有化并使用权限修饰符来实现,同时可以通过方法来访问属性并加入限制条件。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
author-avatar
KenNaNa
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有