1. // 删除
    2. public void delete(int value) {
    3. if (root == null) {
    4. return;
    5. }
    6. // 获取目标节点
    7. Node targetNode = root.search(value);
    8. // 获取父节点
    9. Node parentNode = root.searchParent(value);
    10. if (targetNode == null) {
    11. return;
    12. }
    13. // 特殊情况
    14. if (parentNode == null && (targetNode.left == null || targetNode.right == null)){
    15. if (targetNode.left != null) {
    16. root = targetNode.left;
    17. return;
    18. }else {
    19. root = targetNode.right;
    20. return;
    21. }
    22. }
    23. // 如果该二叉树只有一个节点,且要删除的结就是该节点
    24. if (root.left == null && root.right == null) {
    25. root = null;
    26. return;
    27. }
    28. // 如果目标节点是叶子节点
    29. if (targetNode.left == null && targetNode.right == null) {
    30. // 判断目标节点是其父节点的左节点还是右节点
    31. if (parentNode.left == targetNode) {
    32. parentNode.left = null;
    33. } else {
    34. parentNode.right = null;
    35. }
    36. }
    37. // 如果目标节点只有一个子树
    38. if ((targetNode.left != null && targetNode.right == null
    39. || (targetNode.left == null && targetNode.right != null))) {
    40. // 判断目标节点是其父节点的左节点还是右节点
    41. if (parentNode.left == targetNode) {
    42. // 将目标节点的子节点和目标节点的父节点相连
    43. if (targetNode.left != null) {
    44. parentNode.left = targetNode.left;
    45. }else {
    46. parentNode.left = targetNode.right;
    47. }
    48. }else {
    49. // 将目标节点的子节点和目标节点的父节点相连
    50. if (targetNode.left != null) {
    51. parentNode.right = targetNode.left;
    52. }else {
    53. parentNode.right = targetNode.right;
    54. }
    55. }
    56. }
    57. // 如果目标节点有两个子树
    58. if (targetNode.left != null && targetNode.right != null) {
    59. // 寻找targetNode节点的右子树的最小节点
    60. Node temp = targetNode.right;
    61. // 因为最小值只会出现在左子树,即在右子树中找最底层的左子树
    62. while (temp.left != null) {
    63. temp = temp.left;
    64. }
    65. // 删除这个最小节点(这个必是叶子节点)
    66. delete(temp.value);
    67. // 将targetNode的值换为temp的值
    68. targetNode.value = temp.value;
    69. }
    70. }
    1. // 查找要删除的节点
    2. /**
    3. * @param value 希望删除的节点的值
    4. * @return 返回该节点
    5. */
    6. public Node search(int value) {
    7. if (this.value == value) {
    8. return this;
    9. }
    10. // 向左递归查找
    11. if (value < this.value) {
    12. // 判断this的左节点是否为空
    13. if (this.left == null) {
    14. return null;
    15. } else {
    16. return this.left.search(value);
    17. }
    18. }
    19. // 向右递归查找
    20. if (value > this.value) {
    21. // 判断this的右节点是否为空
    22. if (this.right == null) {
    23. return null;
    24. } else {
    25. return this.right.search(value);
    26. }
    27. }
    28. return null;
    29. }
    30. // 查找目标节点的父节点
    31. /**
    32. * @param value 要删除节点的值
    33. * @return 要删除节点的父节点
    34. */
    35. public Node searchParent(int value) {
    36. // 如果this节点就是目标节点的父节点
    37. if ((this.left != null && this.left.value == value) ||
    38. (this.right != null && this.right.value == value)) {
    39. return this;
    40. }
    41. // 向左递归
    42. if (value < this.value && this.left != null) {
    43. return this.left.searchParent(value);
    44. }
    45. // 向右递归
    46. if (value >= this.value && this.right != null) {
    47. return this.right.searchParent(value);
    48. }
    49. return null;
    50. }

    总代码

    1. package com.atguigu.binarysorttree;
    2. /**
    3. * 二叉排序树
    4. *
    5. * @author Dxkstart
    6. * @create 2022-04-10-15:48
    7. */
    8. public class BinarySortTreeDemo {
    9. public static void main(String[] args) {
    10. int[] arr = new int[]{7, 3, 10, 12, 5, 1, 9, 2};
    11. BinarySortTree binarySortTree = new BinarySortTree();
    12. // 向树中添加
    13. for (int i = 0; i < arr.length; i++) {
    14. binarySortTree.add(new Node(arr[i]));
    15. }
    16. // 遍历
    17. binarySortTree.infixOrder();
    18. System.out.println("=========删除测试=========");
    19. binarySortTree.delete(3);
    20. System.out.println("---新的---");
    21. // 遍历
    22. binarySortTree.infixOrder();
    23. }
    24. }
    25. // 创建二叉排序树
    26. class BinarySortTree {
    27. private Node root;
    28. // 添加节点的方法
    29. public void add(Node node) {
    30. // 如果是空树
    31. if (root == null) {
    32. root = node;
    33. } else {
    34. root.add(node);
    35. }
    36. }
    37. // 中序遍历
    38. public void infixOrder() {
    39. if (root != null) {
    40. root.infixOrder();
    41. } else {
    42. System.out.println("此二叉排序树为空");
    43. }
    44. }
    45. // 删除
    46. public void delete(int value) {
    47. if (root == null) {
    48. return;
    49. }
    50. // 获取目标节点
    51. Node targetNode = root.search(value);
    52. // 获取父节点
    53. Node parentNode = root.searchParent(value);
    54. if (targetNode == null) {
    55. return;
    56. }
    57. // 特殊情况
    58. if (parentNode == null && (targetNode.left == null || targetNode.right == null)){
    59. if (targetNode.left != null) {
    60. root = targetNode.left;
    61. return;
    62. }else {
    63. root = targetNode.right;
    64. return;
    65. }
    66. }
    67. // 如果该二叉树只有一个节点,且要删除的结就是该节点
    68. if (root.left == null && root.right == null) {
    69. root = null;
    70. return;
    71. }
    72. // 如果目标节点是叶子节点
    73. if (targetNode.left == null && targetNode.right == null) {
    74. // 判断目标节点是其父节点的左节点还是右节点
    75. if (parentNode.left == targetNode) {
    76. parentNode.left = null;
    77. } else {
    78. parentNode.right = null;
    79. }
    80. }
    81. // 如果目标节点只有一个子树
    82. if ((targetNode.left != null && targetNode.right == null
    83. || (targetNode.left == null && targetNode.right != null))) {
    84. // 判断目标节点是其父节点的左节点还是右节点
    85. if (parentNode.left == targetNode) {
    86. // 将目标节点的子节点和目标节点的父节点相连
    87. if (targetNode.left != null) {
    88. parentNode.left = targetNode.left;
    89. }else {
    90. parentNode.left = targetNode.right;
    91. }
    92. }else {
    93. // 将目标节点的子节点和目标节点的父节点相连
    94. if (targetNode.left != null) {
    95. parentNode.right = targetNode.left;
    96. }else {
    97. parentNode.right = targetNode.right;
    98. }
    99. }
    100. }
    101. // 如果目标节点有两个子树
    102. if (targetNode.left != null && targetNode.right != null) {
    103. // 寻找targetNode节点的右子树的最小节点
    104. Node temp = targetNode.right;
    105. // 因为最小值只会出现在左子树,即在右子树中找最底层的左子树
    106. while (temp.left != null) {
    107. temp = temp.left;
    108. }
    109. // 删除这个最小节点(这个必是叶子节点)
    110. delete(temp.value);
    111. // 将targetNode的值换为temp的值
    112. targetNode.value = temp.value;
    113. }
    114. }
    115. }
    116. // 创建Node节点
    117. class Node {
    118. int value;
    119. Node left;
    120. Node right;
    121. public Node(int value) {
    122. this.value = value;
    123. }
    124. // 查找要删除的节点
    125. /**
    126. * @param value 希望删除的节点的值
    127. * @return 返回该节点
    128. */
    129. public Node search(int value) {
    130. if (this.value == value) {
    131. return this;
    132. }
    133. // 向左递归查找
    134. if (value < this.value) {
    135. // 判断this的左节点是否为空
    136. if (this.left == null) {
    137. return null;
    138. } else {
    139. return this.left.search(value);
    140. }
    141. }
    142. // 向右递归查找
    143. if (value > this.value) {
    144. // 判断this的右节点是否为空
    145. if (this.right == null) {
    146. return null;
    147. } else {
    148. return this.right.search(value);
    149. }
    150. }
    151. return null;
    152. }
    153. // 查找目标节点的父节点
    154. /**
    155. * @param value 要删除节点的值
    156. * @return 要删除节点的父节点
    157. */
    158. public Node searchParent(int value) {
    159. // 如果this节点就是目标节点的父节点
    160. if ((this.left != null && this.left.value == value) ||
    161. (this.right != null && this.right.value == value)) {
    162. return this;
    163. }
    164. // 向左递归
    165. if (value < this.value && this.left != null) {
    166. return this.left.searchParent(value);
    167. }
    168. // 向右递归
    169. if (value >= this.value && this.right != null) {
    170. return this.right.searchParent(value);
    171. }
    172. return null;
    173. }
    174. // 添加节点的方法
    175. public void add(Node node) {
    176. if (node == null) {
    177. return;
    178. }
    179. // 判断传入的节点的值,和当前子树的根节点的值的关系
    180. if (node.value < this.value) {
    181. // 如果当前节点的左节点为空
    182. if (this.left == null) {
    183. // 直接将该节点挂在this节点的左边
    184. this.left = node;
    185. return;
    186. } else {
    187. // 继续向左递归
    188. this.left.add(node);
    189. }
    190. // 当前节点大于this节点的值
    191. } else if (node.value > this.value) {
    192. // 如果this节点的右节点为空
    193. if (this.right == null) {
    194. // 直接将该节点挂在this节点的右边
    195. this.right = node;
    196. return;
    197. } else {
    198. //继续向右递归
    199. this.right.add(node);
    200. }
    201. }
    202. }
    203. // 中序遍历
    204. public void infixOrder() {
    205. if (this.left != null) {
    206. // 向左递归
    207. this.left.infixOrder();
    208. }
    209. // 中间节点
    210. System.out.println(this.value);
    211. if (this.right != null) {
    212. // 向右递归
    213. this.right.infixOrder();
    214. }
    215. }
    216. @Override
    217. public String toString() {
    218. return "Node{" +
    219. "value=" + value +
    220. '}';
    221. }
    222. }