比起2节点二叉树的删除操作,3节点的删除更加舒服一点,减少了很多扯蛋蛋的操作,加一个parent的只不过添加了一点点空间而已。

    1. package io.github.chenshun00.web.tree;
    2. /**
    3. * @author luobo.cs@raycloud.com
    4. * @since 2021/8/13 1:24 下午
    5. */
    6. public class BinaryTree2 {
    7. public static void main(String[] args) {
    8. BinaryTree2 binaryTree = new BinaryTree2();
    9. binaryTree.insertNode(22);
    10. binaryTree.insertNode(1);
    11. binaryTree.insertNode(4);
    12. binaryTree.insertNode(3);
    13. binaryTree.insertNode(10);
    14. binaryTree.insertNode(9);
    15. binaryTree.insertNode(9);
    16. binaryTree.insertNode(8);
    17. binaryTree.insertNode(190);
    18. binaryTree.insertNode(11);
    19. binaryTree.insertNode(12);
    20. binaryTree.insertNode(13);
    21. binaryTree.insertNode(231);
    22. binaryTree.insertNode(22);
    23. binaryTree.traverse();
    24. System.out.println("删除节点:===>" + binaryTree.deleteNode(9));
    25. binaryTree.traverse();
    26. System.out.println("删除节点:===>" + binaryTree.deleteNode(13));
    27. binaryTree.traverse();
    28. System.out.println("删除节点:===>" + binaryTree.deleteNode(22));
    29. binaryTree.traverse();
    30. System.out.println("删除节点:===>" + binaryTree.deleteNode(22));
    31. binaryTree.traverse();
    32. }
    33. public Node root;
    34. public boolean deleteNode(Integer data) {
    35. if (root == null) {
    36. return false;
    37. }
    38. //找到当前节点
    39. final Node node = doFindNode(data);
    40. //找不到节点的情况
    41. if (node == null) {
    42. return false;
    43. }
    44. //如果节点是根节点
    45. if (node == root) {
    46. //如果根节点是叶子节点
    47. if (isLeaf(root)) {
    48. root = null;
    49. } else {
    50. replace(root);
    51. }
    52. return true;
    53. }
    54. //被移除的是叶子节点
    55. if (isLeaf(node)) {
    56. //找到叶子节点的parent节点,并且说明当前节点是左(left)子树还是右子树(right)
    57. final Node parent = node.parent;
    58. if (parent.leftChild == node) {
    59. parent.leftChild = null;
    60. } else {
    61. parent.rightChild = null;
    62. }
    63. } else {
    64. replace(node);
    65. }
    66. return true;
    67. }
    68. public Node findNode(Integer data) {
    69. return root == null ? null : doFindNode(data);
    70. }
    71. public void insertNode(Integer data) {
    72. if (root == null) {
    73. root = new Node(null, null, null, data);
    74. } else {
    75. handleData(root, data);
    76. }
    77. }
    78. public void traverse() {
    79. doTraverse(root);
    80. System.out.println();
    81. }
    82. //==============================删==================================
    83. private void replace(Node node) {
    84. //找到左子树中最大的节点 或者 是右子树中最小的节点
    85. final Node next = findNext(node);
    86. final Node parent = next.parent;
    87. if (parent.leftChild == next) {
    88. parent.leftChild = null;
    89. } else if (parent.rightChild == next) {
    90. parent.rightChild = null;
    91. }
    92. node.data = next.data;
    93. }
    94. private Node findNext(Node node) {
    95. if (node.leftChild != null) {
    96. return doFindMaxNode(node.leftChild);
    97. }
    98. return doFindMinNode(node.rightChild);
    99. }
    100. private Node doFindMaxNode(Node node) {
    101. if (node.rightChild == null) {
    102. return node;
    103. } else {
    104. return doFindMaxNode(node.rightChild);
    105. }
    106. }
    107. private Node doFindMinNode(Node node) {
    108. if (node.leftChild == null) {
    109. return node;
    110. } else {
    111. return doFindMinNode(node.leftChild);
    112. }
    113. }
    114. public boolean isLeaf(Node node) {
    115. return node.leftChild == null && node.rightChild == null;
    116. }
    117. //==============================查==================================
    118. private Node doFindNode(Integer data) {
    119. return data >= root.data ? findRight(root, data) : findLeft(root, data);
    120. }
    121. /**
    122. * 找到右
    123. *
    124. * @param root 根
    125. * @param data 数据
    126. * @return {@link Node}
    127. */
    128. private Node findRight(Node root, Integer data) {
    129. if (root == null) {
    130. return null;
    131. }
    132. if (root.data.equals(data)) {
    133. return root;
    134. }
    135. if (data >= root.data) {
    136. //右子树
    137. return findRight(root.rightChild, data);
    138. } else {
    139. //左子树
    140. return findLeft(root.leftChild, data);
    141. }
    142. }
    143. private Node findLeft(Node root, Integer data) {
    144. if (root == null) {
    145. return null;
    146. }
    147. if (root.data.equals(data)) {
    148. return root;
    149. }
    150. if (data >= root.data) {
    151. //右子树
    152. return findRight(root.rightChild, data);
    153. } else {
    154. //左子树
    155. return findLeft(root.leftChild, data);
    156. }
    157. }
    158. //==============================遍历==================================
    159. private void doTraverse(Node node) {
    160. if (node == null) {
    161. System.out.println("么数据");
    162. return;
    163. }
    164. if (node.leftChild != null) {
    165. doTraverse(node.leftChild);
    166. }
    167. System.out.print(node.data + "\t");
    168. if (node.rightChild != null) {
    169. doTraverse(node.rightChild);
    170. }
    171. }
    172. //=================插入数据=====================
    173. private void handleData(Node root, Integer data) {
    174. if (data >= root.data) {
    175. handleRight(root, root.rightChild, data);
    176. } else {
    177. handleLeft(root, root.leftChild, data);
    178. }
    179. }
    180. //处理右子树
    181. private void handleRight(Node root, Node right, Integer data) {
    182. if (right == null) {
    183. right = new Node(null, null, root, data);
    184. root.rightChild = right;
    185. } else {
    186. handleData(right, data);
    187. }
    188. }
    189. //处理左子树
    190. private void handleLeft(Node root, Node left, Integer data) {
    191. if (left == null) {
    192. left = new Node(null, null, root, data);
    193. root.leftChild = left;
    194. } else {
    195. handleData(left, data);
    196. }
    197. }
    198. public static class Node {
    199. public Node(Node leftChild, Node rightChild, Node parent, Integer data) {
    200. this.leftChild = leftChild;
    201. this.rightChild = rightChild;
    202. this.parent = parent;
    203. this.data = data;
    204. }
    205. public Node leftChild;
    206. public Node rightChild;
    207. public Node parent;
    208. public Integer data;
    209. }
    210. }