文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java编程内功-数据结构与算法「二叉排序树」

2024-12-03 08:23

关注

**特别说明:**如果有相同的值,可以将该节点放在左子节点或者右子节点

比如针对数据{7,3,10,12,5,1,9},对应的二叉排序树为:

二叉排序树删除节点

二叉排序树的删除情况比较复杂,如下图,有下面三种情况需要考虑,

删除叶子节点(比如:2,5,9,12)

  1. 需要先找到要删除的节点 targetNode
  2. 找到 targetNode 的父节点 parentNode(考虑是否存在父节点)
  3. 确定 targetNode 是 parentNode 的左子节点还是右子节点
  4. 根据前面的来对应删除,左子节点=>parent.left = null,右子节点=>parent.right = null;

删除只有一颗子树的节点(比如:1)

  1. 需要先找到要删除的节点 targetNode
  2. 找到 targetNode 的父节点 parentNode(考虑是否存在父节点)
  3. 确定 targetNode 的子节点是左子节点还是右子节点
  4. 确定 targetNode 是 parentNode 的左子节点还是右子节点
  5. 如果 targetNode 是parentNode 的左子节点 :

删除有两颗子树的节点(比如:7,3,10)

  1. 需要先找到要删除的节点 targetNode
  2. 找到 targetNode 的父节点 parentNode(考虑是否存在父节点)
  3. 从 targetNode 的右子树找到最小的节点,用一个临时变量,将右子树最小节点的值保存到temp ,删除该右子树最小节点,然后,targetNode.value = temp;如果从左子树找的话,只要替换左子树最大的值就行。

代码案例:

  1. package com.xie.bst; 
  2.  
  3. public class BinarySortTreeDemo { 
  4.     public static void main(String[] args) { 
  5.         int[] arr = {7, 3, 10, 12, 5, 1, 9, 2}; 
  6.         BinarySortTree binarySortTree = new BinarySortTree(); 
  7.         for (int i : arr) { 
  8.             binarySortTree.add(new Node(i)); 
  9.         } 
  10.         System.out.println("中序遍历二叉排序树~"); 
  11.         binarySortTree.infixOrder(); 
  12.  
  13.         System.out.println("测试删除叶子节点"); 
  14.         binarySortTree.delNode(10); 
  15.         System.out.println("删除节点后"); 
  16.         binarySortTree.infixOrder(); 
  17.     } 
  18.  
  19. class BinarySortTree { 
  20.     private Node root; 
  21.  
  22.     //查找要删除的节点的父节点 
  23.     public Node searchParent(Node node) { 
  24.         if (root != null) { 
  25.             return root.searchParent(node); 
  26.         } else { 
  27.             return null
  28.         } 
  29.     } 
  30.  
  31.     //查找要删除的节点 
  32.     public Node search(int value) { 
  33.         if (root == null) { 
  34.             return null
  35.         } else { 
  36.             return root.search(value); 
  37.         } 
  38.     } 
  39.  
  40.      
  41.     public int delRightTreeMin(Node node) { 
  42.         Node target = node; 
  43.         //循环查找左节点 
  44.         while (target.left != null) { 
  45.             target = target.left
  46.         } 
  47.         //删除最小节点 
  48.         delNode(target.value); 
  49.         return target.value; 
  50.     } 
  51.  
  52.      
  53.     public int delLeftTreeMax(Node node) { 
  54.         Node target = node; 
  55.         while (target.right != null) { 
  56.             target = target.right
  57.         } 
  58.  
  59.         //删除最大节点 
  60.         delNode(target.value); 
  61.         return target.value; 
  62.     } 
  63.  
  64.     //删除节点 
  65.     public void delNode(int value) { 
  66.         if (root == null) { 
  67.             return
  68.         } else { 
  69.             Node targetNode = search(value); 
  70.             if (targetNode == null) { 
  71.                 return
  72.             } 
  73.             if (targetNode == root) { 
  74.                 root = null
  75.                 return
  76.             } 
  77.             Node parentNode = searchParent(targetNode); 
  78.  
  79.             if (targetNode.left == null && targetNode.right == null) { 
  80.                 //如果要删除的节点是叶子节点 
  81.                 if (parentNode.left != null && parentNode.left.value == targetNode.value) { 
  82.                     parentNode.left = null
  83.                 } 
  84.                 if (parentNode.right != null && parentNode.right.value == targetNode.value) { 
  85.                     parentNode.right = null
  86.                 } 
  87.             } else if (targetNode.left != null && targetNode.right != null) { 
  88.                 //如果要删除的节点是有两个子树的节点 
  89.                 int minValue = delRightTreeMin(targetNode.right); 
  90.                 targetNode.value = minValue; 
  91.                 //上下代码删除效果一样 
  92.                 //int maxValue = delLeftTreeMax(targetNode.left); 
  93.                 //targetNode.value = maxValue; 
  94.             } else { 
  95.                 //要删除的节点是只有左子节点 
  96.                 if (targetNode.left != null) { 
  97.                     if (parentNode != null) { 
  98.                         if (parentNode.left == targetNode) { 
  99.                             parentNode.left = targetNode.left
  100.                         } else { 
  101.                             parentNode.right = targetNode.left
  102.                         } 
  103.                     } else { 
  104.                         //如果父节点是空,让root换位 
  105.                         root = targetNode.left
  106.                     } 
  107.                 } else {//要删除的节点是只有右子节点 
  108.                     if (parentNode != null) { 
  109.                         if (parentNode.left == targetNode) { 
  110.                             parentNode.left = targetNode.right
  111.                         } else { 
  112.                             parentNode.right = targetNode.right
  113.                         } 
  114.                     } else { 
  115.                         //如果父节点是空,让root换位 
  116.                         root = targetNode.right
  117.                     } 
  118.  
  119.                 } 
  120.             } 
  121.         } 
  122.     } 
  123.  
  124.     //添加节点 
  125.     public void add(Node node) { 
  126.         if (root == null) { 
  127.             root = node; 
  128.         } else { 
  129.             root.add(node); 
  130.         } 
  131.     } 
  132.  
  133.     //中序遍历 
  134.     public void infixOrder() { 
  135.         if (root != null) { 
  136.             root.infixOrder(); 
  137.         } else { 
  138.             System.out.println("二叉排序为空,不能遍历"); 
  139.         } 
  140.     } 
  141.  
  142.  
  143. class Node { 
  144.     int value; 
  145.     Node left
  146.     Node right
  147.  
  148.     public Node(int value) { 
  149.         this.value = value; 
  150.     } 
  151.  
  152.      
  153.     public Node searchParent(Node node) { 
  154.         //如果当前节点就是要删除节点的父节点就返回 
  155.         if ((this.left != null && this.left.value == node.value) || 
  156.                 (this.right != null && this.right.value == node.value)) { 
  157.             return this; 
  158.         } else { 
  159.             if (this.left != null && node.value < this.value) { 
  160.                 //如果查找的节点的值小于当前节点的值,向左子树递归查找 
  161.                 return this.left.searchParent(node); 
  162.             } else if (this.right != null && value >= this.value) { 
  163.                 //如果查找的节点的值小于当前节点的值,向左子树递归查找 
  164.                 return this.right.searchParent(node); 
  165.             } else { 
  166.                 return null
  167.             } 
  168.         } 
  169.     } 
  170.  
  171.      
  172.     public Node search(int value) { 
  173.         if (value == this.value) { 
  174.             return this; 
  175.         } else if (value < this.value) { 
  176.             if (this.left != null) { 
  177.                 return this.left.search(value); 
  178.             } else { 
  179.                 return null
  180.             } 
  181.         } else { 
  182.             if (this.right != null) { 
  183.                 return this.right.search(value); 
  184.             } else { 
  185.                 return null
  186.             } 
  187.         } 
  188.     } 
  189.  
  190.     //递归的形式添加节点,满足二叉排序树的要求 
  191.     public void add(Node node) { 
  192.         if (node == null) { 
  193.             return
  194.         } 
  195.         if (node.value < this.value) { 
  196.             if (this.left == null) { 
  197.                 this.left = node; 
  198.             } else { 
  199.                 //递归向左子树添加 
  200.                 this.left.add(node); 
  201.             } 
  202.         } else { 
  203.             if (this.right == null) { 
  204.                 this.right = node; 
  205.             } else { 
  206.                 //递归向右子节点添加 
  207.                 this.right.add(node); 
  208.             } 
  209.         } 
  210.     } 
  211.  
  212.     //中序遍历 
  213.     public void infixOrder() { 
  214.         if (this.left != null) { 
  215.             this.left.infixOrder(); 
  216.         } 
  217.         System.out.println(this); 
  218.         if (this.right != null) { 
  219.             this.right.infixOrder(); 
  220.         } 
  221.     } 
  222.  
  223.     @Override 
  224.     public String toString() { 
  225.         return "Node{" + 
  226.                 "value=" + value + 
  227.                 '}'
  228.     } 

 【编辑推荐】

  1. 微服务面试必问的Dubbo,这么详细还怕自己找不到工作?
  2. 2021年值得关注的5个IT行业发展趋势
  3. 免费的安全软件落寞!让人唏嘘
  4. 界面UI即将大改!Windows1021H2最新预览版抢先看
  5. 微软为 Windows101909 推送 KB5000850 更新,修复资源管理器搜索等问题

 

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯