• 二叉查找树的综合应用


    一 需求

    实现二叉查找树的搜索、插入、删除操作。

    二 代码

    1. package bst;
    2. import java.util.Scanner;
    3. public class BST {
    4. static int ENDFLAG = -1;
    5. // 二叉排序树的递归查找
    6. static public TreeNode search(TreeNode root, int val) {
    7. // 若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
    8. if ((root == null) || val == root.val)
    9. return root;
    10. else if (val < root.val)
    11. return search(root.left, val); // 在左子树中继续查找
    12. else
    13. return search(root.right, val); // 在右子树中继续查找
    14. }
    15. // 二叉排序树的插入
    16. static public TreeNode Insert(TreeNode root, int val) {
    17. if (root == null) {
    18. // 树为空树的情况
    19. return new TreeNode(val);
    20. }
    21. // 一个临时节点指向根节点,用于返回值
    22. TreeNode tmp = root;
    23. TreeNode pre = root;
    24. while (root != null && root.val != val) {
    25. // 保存父节点
    26. pre = root;
    27. if (val > root.val) {
    28. root = root.right;
    29. } else {
    30. root = root.left;
    31. }
    32. }
    33. // 通过父节点添加
    34. if (val > pre.val) {
    35. pre.right = new TreeNode(val);
    36. } else {
    37. pre.left = new TreeNode(val);
    38. }
    39. return tmp;
    40. }
    41. // 二叉排序树的创建
    42. static TreeNode CreateBST(TreeNode node) {
    43. Scanner scanner = new Scanner(System.in);
    44. // 依次读入一个关键字为key的结点,将此结点插入二叉排序树T中
    45. int e;
    46. e = scanner.nextInt();
    47. while (e != ENDFLAG) // ENDFLAG为自定义常量,作为输入结束标志
    48. {
    49. node = Insert(node, e); // 插入二叉排序树T中
    50. e = scanner.nextInt();
    51. }
    52. return node;
    53. }
    54. // 二叉排序树的删除
    55. static public TreeNode DeleteBST(TreeNode root, int key) {
    56. TreeNode tmp = root;
    57. TreeNode pre = root;
    58. // 寻找要删除的节点
    59. while (root != null && root.val != key) {
    60. pre = root;
    61. if (key > root.val) {
    62. root = root.right;
    63. } else {
    64. root = root.left;
    65. }
    66. }
    67. // 找不到符合的节点值
    68. if (root == null) {
    69. return tmp;
    70. }
    71. // 只有一个子节点或者没有子节点的情况
    72. if (root.left == null || root.right == null) {
    73. if (root.left == null) {
    74. // 要删除的是根节点,返回它的子节点
    75. if (root == tmp) {
    76. return root.right;
    77. }
    78. // 使用父节点连接子节点,实现删除当前节点
    79. if (pre.left == root) {
    80. pre.left = root.right;
    81. } else {
    82. pre.right = root.right;
    83. }
    84. } else {
    85. if (root == tmp) {
    86. return root.left;
    87. }
    88. if (pre.left == root) {
    89. pre.left = root.left;
    90. } else {
    91. pre.right = root.left;
    92. }
    93. }
    94. return tmp;
    95. }
    96. // 寻找中序遍历的后一个节点,也就是右子树进行中序遍历的第一个节点,右子树的最左节点
    97. pre = root;
    98. TreeNode rootRight = root.right;
    99. while (rootRight.left != null) {
    100. pre = rootRight;
    101. rootRight = rootRight.left;
    102. }
    103. // 节点的值进行交换
    104. int tmpVal = rootRight.val;
    105. rootRight.val = root.val;
    106. root.val = tmpVal;
    107. // 中序遍历的第一个节点肯定是没有左子树的,但是可能有右子树,将右子树连接到父节点上(相当于删除有一个子节点的节点)
    108. if (pre.left == rootRight) {
    109. pre.left = rootRight.right;
    110. } else {
    111. pre.right = rootRight.right;
    112. }
    113. return tmp;
    114. }
    115. // 中序遍历
    116. static public void preorder(TreeNode root) {
    117. if (root == null) {
    118. return;
    119. }
    120. if (root.left != null) {
    121. preorder(root.left);
    122. }
    123. System.out.print(root.val + " ");
    124. if (root.right != null) {
    125. preorder(root.right);
    126. }
    127. }
    128. public static void main(String[] args) {
    129. TreeNode node = null;
    130. System.out.println("请输入一些整型数,-1结束");
    131. node = CreateBST(node);
    132. System.out.println("当前有序二叉树中序遍历结果为");
    133. preorder(node);
    134. System.out.println();
    135. int key; // 待查找或待删除内容
    136. System.out.println("请输入待查找关键字");
    137. Scanner scanner = new Scanner(System.in);
    138. key = scanner.nextInt();
    139. TreeNode result = search(node, key);
    140. if (result != null)
    141. System.out.println("找到" + key);
    142. else
    143. System.out.println("未找到" + key);
    144. key = scanner.nextInt();
    145. DeleteBST(node, key);
    146. System.out.println("当前有序二叉树中序遍历结果为");
    147. preorder(node);
    148. }
    149. }
    150. class TreeNode {
    151. int val;
    152. TreeNode left;
    153. TreeNode right;
    154. TreeNode(int val) {
    155. this.val = val;
    156. }
    157. }

    三 测试

    绿色为输入,白色为输出。

  • 相关阅读:
    Datax抽取mysql的bit类型数据
    【linux进程(一)】深入理解进程概念--什么是进程?PCB的底层是什么?
    算法-简单-二叉树-翻转、对称
    FFmpeg源码剖析-通用:ffmpeg_parse_options()
    vite+vue+cesium搭建工程:有社区插件方便
    matlab server-client传输数据
    leetcode:2446. 判断两个事件是否存在冲突(python3解法)
    SQL 存储过程优化
    docker搭建 Nexus3 私服
    HDC2022重磅发布“鸿蒙赋能全家桶”,开发者的新时代要来了?
  • 原文地址:https://blog.csdn.net/chengqiuming/article/details/126130130