• 二叉搜索树


    目录

    一、概念

    二、插入数据

    三、查找数据

    四、删除数据


    一、概念

    二叉搜索树:又称为二叉排序树,它或是一棵空树,或是一棵具有以下性质的二叉树:

    (1)若它的左子树不为空,则左子树上的所有节点的值都小于根节点的值

    (2)若它的右子树不为空,则右子树上的所有节点的值都大于根节点的值

    (3)它的左右子树也分别是二叉搜索树

    例如:

    图中二叉搜索树中序遍历的结果:3 5 7 10 11 12 40  

    由于二叉搜索树的性质,二叉搜索树中序遍历结果是升序

    二、插入数据

    若二叉搜索树为空树,则直接将节点放在根节点位置处。

    若二叉搜索树不为空树,由二叉树的性质(左子树上的所有节点的值都小于根节点的值,右子树上的所有节点的值都大于根节点的值),可通过比较插入节点和当前节点cur的值,找到插入节点的位置

     

     找到插入节点的位置后,要通过cur的父亲节点将插入节点连接起来,因此我们可以定义一个parent节点,指向cur的父亲节点,来帮助我们插入节点

    若插入的值与二叉搜索树中节点的值相同,则插入失败,返回false

    代码实现:

    1. public class BinarySearchTree {
    2. static class Node{
    3. private int val;
    4. private Node left;
    5. private Node right;
    6. public Node(int val){
    7. this.val = val;
    8. }
    9. }
    10. //创建根节点
    11. public Node root;
    12. //插入数据
    13. public boolean insert(int val){
    14. Node node = new Node(val);
    15. //根节点为空,直接将数据放在根节点位置
    16. if(root == null){
    17. root = node;
    18. return true;
    19. }
    20. //不为根节点,查找插入位置
    21. Node cur = root;
    22. Node parent = null;
    23. while(cur != null){
    24. if(node.val < cur.val){
    25. parent = cur;
    26. cur = cur.left;
    27. }else if(node.val > cur.val){
    28. parent = cur;
    29. cur = cur.right;
    30. }else {//若相等,则插入失败
    31. return false;
    32. }
    33. }
    34. if(parent.val > node.val){
    35. parent.left = node;
    36. }else{
    37. parent.right = node;
    38. }
    39. return true;
    40. }
    41. }

    三、查找数据

    将待查找数据data与节点的值进行比较,若相同,则返回;若data小于节点的值,则向左子树继续查找;若data大于节点的值,则向右子树继续查找

    代码实现:

    1. public boolean search(int data){
    2. if(root == null){//若根节点为null,无数据,直接返回false
    3. return false;
    4. }
    5. Node cur = root;
    6. while(cur != null){
    7. if(data == cur.val){
    8. return true;
    9. }else if(data < cur.val){
    10. cur = cur.left;
    11. }else{
    12. cur = cur.right;
    13. }
    14. }
    15. return false;
    16. }

    四、删除数据

    当删除二叉搜索树中节点时,需分情况删除

    待删除节点为cur,其父亲节点为parent

    1. cur.left = null

    (1)若cur = root,则root = cur.right

    (2)若cur != root 且 cur = parent.left ,则parent.left = cur.right

    (3)若cur != root 且 cur = parent.right,则parent.right = cur.right

    2. cur.right = null

    (1)cur = root,则 root = cur.right

    (2)cur != root 且 cur = parent.left,则parent.left = cur.left

    (3)cur != root 且 cur = parent.right,则parent.right = cur.left

    3. cur.left != null 且 cur.right != null

    此时通过替换进行删除

    由于cur中的数据比左子树大,比右子树小,因此我们可以在左子树中寻找最大的数据(即左子树中最右边的数据),或是在右子树寻找最小的数据(即右子树中最左的数据),用找到的值替换掉cur,再删除找到的值

    由于替换的值为右子树最左的节点(或左子树最右的节点),此时删除的情况变为 2 中的(2)或(3)(或是 1 中的(2)或(3)),便于删除

    代码实现:

    1. public boolean remove(int key){
    2. Node cur = root;
    3. Node parent = null;
    4. while(cur != null){
    5. //找到需删除节点
    6. if(cur.val < key){
    7. parent = cur;
    8. cur = cur.right;
    9. }else if(cur.val > key){
    10. parent = cur;
    11. cur = cur.left;
    12. }else {//找到了,开始删除
    13. removeNode(cur,parent);
    14. return true;
    15. }
    16. }
    17. //未找到,删除失败
    18. return false;
    19. }
    20. private void removeNode(Node cur, Node parent){
    21. if(cur.left == null){
    22. if(cur == root){
    23. root = cur.right;
    24. }else if(parent.left == cur){
    25. parent.left = cur.right;
    26. }else{
    27. parent.right = cur.right;
    28. }
    29. }else if(cur.right == null){
    30. if(cur == root){
    31. root = cur.left;
    32. }else if(parent.left == cur){
    33. parent.left = cur.left;
    34. }else{
    35. parent.right = cur.left;
    36. }
    37. }else {
    38. Node targetParent = cur;
    39. Node target = cur.right;
    40. //在cur的右子树查找最小值
    41. while(target.left != null){
    42. targetParent = target;
    43. target = target.left;
    44. }
    45. //将cur的值替换为target的值
    46. cur.val = target.val;
    47. if(targetParent.left == target){
    48. targetParent.left = target.right;
    49. }else {
    50. targetParent.right = target.right;
    51. }
    52. }
    53. }

  • 相关阅读:
    Windows 系统引导过程
    java-net-php-python-jspm足球队信息管理系统计算机毕业设计程序
    基于JAVA运动场所预约管理网站计算机毕业设计源码+系统+数据库+lw文档+部署
    RHCSA之linux的简单使用
    Linux基础IO
    XSS详解及复现gallerycms字符长度限制短域名绕过
    第三章【ADFS集成Exchang实现OWA\ECP单点登录SSO】配置AD证书服务(配置ADCS)
    1024共码未来(一览中华风华,API First)
    【Eclipse】安装教程
    Netty selector的运行
  • 原文地址:https://blog.csdn.net/2301_76161469/article/details/134019021