// 删除public void delete(int value) {if (root == null) {return;}// 获取目标节点Node targetNode = root.search(value);// 获取父节点Node parentNode = root.searchParent(value);if (targetNode == null) {return;}// 特殊情况if (parentNode == null && (targetNode.left == null || targetNode.right == null)){if (targetNode.left != null) {root = targetNode.left;return;}else {root = targetNode.right;return;}}// 如果该二叉树只有一个节点,且要删除的结就是该节点if (root.left == null && root.right == null) {root = null;return;}// 如果目标节点是叶子节点if (targetNode.left == null && targetNode.right == null) {// 判断目标节点是其父节点的左节点还是右节点if (parentNode.left == targetNode) {parentNode.left = null;} else {parentNode.right = null;}}// 如果目标节点只有一个子树if ((targetNode.left != null && targetNode.right == null|| (targetNode.left == null && targetNode.right != null))) {// 判断目标节点是其父节点的左节点还是右节点if (parentNode.left == targetNode) {// 将目标节点的子节点和目标节点的父节点相连if (targetNode.left != null) {parentNode.left = targetNode.left;}else {parentNode.left = targetNode.right;}}else {// 将目标节点的子节点和目标节点的父节点相连if (targetNode.left != null) {parentNode.right = targetNode.left;}else {parentNode.right = targetNode.right;}}}// 如果目标节点有两个子树if (targetNode.left != null && targetNode.right != null) {// 寻找targetNode节点的右子树的最小节点Node temp = targetNode.right;// 因为最小值只会出现在左子树,即在右子树中找最底层的左子树while (temp.left != null) {temp = temp.left;}// 删除这个最小节点(这个必是叶子节点)delete(temp.value);// 将targetNode的值换为temp的值targetNode.value = temp.value;}}
// 查找要删除的节点/*** @param value 希望删除的节点的值* @return 返回该节点*/public Node search(int value) {if (this.value == value) {return this;}// 向左递归查找if (value < this.value) {// 判断this的左节点是否为空if (this.left == null) {return null;} else {return this.left.search(value);}}// 向右递归查找if (value > this.value) {// 判断this的右节点是否为空if (this.right == null) {return null;} else {return this.right.search(value);}}return null;}// 查找目标节点的父节点/*** @param value 要删除节点的值* @return 要删除节点的父节点*/public Node searchParent(int value) {// 如果this节点就是目标节点的父节点if ((this.left != null && this.left.value == value) ||(this.right != null && this.right.value == value)) {return this;}// 向左递归if (value < this.value && this.left != null) {return this.left.searchParent(value);}// 向右递归if (value >= this.value && this.right != null) {return this.right.searchParent(value);}return null;}
总代码
package com.atguigu.binarysorttree;/*** 二叉排序树** @author Dxkstart* @create 2022-04-10-15:48*/public class BinarySortTreeDemo {public static void main(String[] args) {int[] arr = new int[]{7, 3, 10, 12, 5, 1, 9, 2};BinarySortTree binarySortTree = new BinarySortTree();// 向树中添加for (int i = 0; i < arr.length; i++) {binarySortTree.add(new Node(arr[i]));}// 遍历binarySortTree.infixOrder();System.out.println("=========删除测试=========");binarySortTree.delete(3);System.out.println("---新的---");// 遍历binarySortTree.infixOrder();}}// 创建二叉排序树class BinarySortTree {private Node root;// 添加节点的方法public void add(Node node) {// 如果是空树if (root == null) {root = node;} else {root.add(node);}}// 中序遍历public void infixOrder() {if (root != null) {root.infixOrder();} else {System.out.println("此二叉排序树为空");}}// 删除public void delete(int value) {if (root == null) {return;}// 获取目标节点Node targetNode = root.search(value);// 获取父节点Node parentNode = root.searchParent(value);if (targetNode == null) {return;}// 特殊情况if (parentNode == null && (targetNode.left == null || targetNode.right == null)){if (targetNode.left != null) {root = targetNode.left;return;}else {root = targetNode.right;return;}}// 如果该二叉树只有一个节点,且要删除的结就是该节点if (root.left == null && root.right == null) {root = null;return;}// 如果目标节点是叶子节点if (targetNode.left == null && targetNode.right == null) {// 判断目标节点是其父节点的左节点还是右节点if (parentNode.left == targetNode) {parentNode.left = null;} else {parentNode.right = null;}}// 如果目标节点只有一个子树if ((targetNode.left != null && targetNode.right == null|| (targetNode.left == null && targetNode.right != null))) {// 判断目标节点是其父节点的左节点还是右节点if (parentNode.left == targetNode) {// 将目标节点的子节点和目标节点的父节点相连if (targetNode.left != null) {parentNode.left = targetNode.left;}else {parentNode.left = targetNode.right;}}else {// 将目标节点的子节点和目标节点的父节点相连if (targetNode.left != null) {parentNode.right = targetNode.left;}else {parentNode.right = targetNode.right;}}}// 如果目标节点有两个子树if (targetNode.left != null && targetNode.right != null) {// 寻找targetNode节点的右子树的最小节点Node temp = targetNode.right;// 因为最小值只会出现在左子树,即在右子树中找最底层的左子树while (temp.left != null) {temp = temp.left;}// 删除这个最小节点(这个必是叶子节点)delete(temp.value);// 将targetNode的值换为temp的值targetNode.value = temp.value;}}}// 创建Node节点class Node {int value;Node left;Node right;public Node(int value) {this.value = value;}// 查找要删除的节点/*** @param value 希望删除的节点的值* @return 返回该节点*/public Node search(int value) {if (this.value == value) {return this;}// 向左递归查找if (value < this.value) {// 判断this的左节点是否为空if (this.left == null) {return null;} else {return this.left.search(value);}}// 向右递归查找if (value > this.value) {// 判断this的右节点是否为空if (this.right == null) {return null;} else {return this.right.search(value);}}return null;}// 查找目标节点的父节点/*** @param value 要删除节点的值* @return 要删除节点的父节点*/public Node searchParent(int value) {// 如果this节点就是目标节点的父节点if ((this.left != null && this.left.value == value) ||(this.right != null && this.right.value == value)) {return this;}// 向左递归if (value < this.value && this.left != null) {return this.left.searchParent(value);}// 向右递归if (value >= this.value && this.right != null) {return this.right.searchParent(value);}return null;}// 添加节点的方法public void add(Node node) {if (node == null) {return;}// 判断传入的节点的值,和当前子树的根节点的值的关系if (node.value < this.value) {// 如果当前节点的左节点为空if (this.left == null) {// 直接将该节点挂在this节点的左边this.left = node;return;} else {// 继续向左递归this.left.add(node);}// 当前节点大于this节点的值} else if (node.value > this.value) {// 如果this节点的右节点为空if (this.right == null) {// 直接将该节点挂在this节点的右边this.right = node;return;} else {//继续向右递归this.right.add(node);}}}// 中序遍历public void infixOrder() {if (this.left != null) {// 向左递归this.left.infixOrder();}// 中间节点System.out.println(this.value);if (this.right != null) {// 向右递归this.right.infixOrder();}}@Overridepublic String toString() {return "Node{" +"value=" + value +'}';}}
