二叉排序樹刪除
阿新 • • 發佈:2020-10-28
二叉排序樹的刪除情況比較複雜,有以下三種情況需要考慮
- 刪除葉子節點(比如:2,5,9,12)
- 刪除只有一棵子樹的節點(比如1)
- 刪除有兩棵子樹的節點(比如:7,3,10)
- 操作思路分析
第一種情況:刪除葉子節點
思路:
-
- 需要先找到待刪除的節點 targetNode
-
- 找到targetNode的父節點 parent
-
- 確定targetNode是parent的左節點還是右節點
-
- 根據左右來進行刪除
- 左子節點 parent.left = null
- 右子節點 parent.right = null
第二種情況:刪除只有一棵子樹的節點,比如1
思路:
-
- 需要先找到待刪除的節點targetNode
-
- 找到targetNode的父節點 parent
-
- 確定targetNode的子節點是左子節點還是又子節點
-
- targetNode是parent的左子節點還是右子節點
-
- 如果targetNode有左子節點
- 5.1. 如果targetNode是parent的左子節點 parent.left = targetNode.left
- 5.2. 如果targetNode是parent的右子節點 parent.right = targetNode.left
-
- 如果targetNode有右子節點
- 6.1. 如果targetNode是parent的左子節點 parent.left = targetNode.right
- 6.2 如果targetNode是parent的右子節點 parent.right = targetNode.right
第三種情況:刪除有兩棵子樹的節點(比如:7,3,10)
思路:
-
- 需要先找到待刪除的節點 targetNode
-
- 找到targetNode的父節點 parent
-
- 從targetNode的右子樹中找到最小的節點
-
- 用一個臨時變數,將最小的節點值儲存在temp中
-
- 刪除該最小的節點
-
- targetNode.val = temp
public class BinarySortTreeDemo { public static void main(String[] args) { int[] arr = {7, 3, 10, 12, 5, 1, 9,2}; BinarySortTree binarySortTree = new BinarySortTree(); for (int i = 0; i < arr.length; i++) { binarySortTree.addNode(new Node(arr[i])); } //遍歷 binarySortTree.midOrder(); //測試刪除節點 binarySortTree.delNode(5); binarySortTree.delNode(9); binarySortTree.delNode(10); binarySortTree.delNode(12); binarySortTree.delNode(7); binarySortTree.delNode(1); binarySortTree.delNode(2); binarySortTree.delNode(3); System.out.println("刪除後"); binarySortTree.midOrder(); } } class BinarySortTree { private Node root; //新增節點 public void addNode(Node node) { if (root == null) { root = node; } else { root.addNode(node); } } //中序遍歷節點 public void midOrder() { if (root == null) { System.out.println("二叉排序樹為空"); } else { root.midOrder(); } } //查詢待刪除的節點 public Node searchNode(int val) { if (this.root == null) { return null; } else { return this.root.serachNode(val); } } //查詢待刪除的父節點 public Node searchParentNode(int val) { if (this.root == null) { return null; } else { return this.root.searchParentNode(val); } } //在待查詢二叉樹中找到最小的節點 public int searchRightMin(Node node){ while (node.left != null){ node = node.left; } delNode(node.val); //刪除最小的節點 return node.val; //返回最小的節點值 } //刪除節點 public void delNode(int val) { if (this.root == null) { return; } else { //先拿到待刪除的節點 Node targetNode = searchNode(val); if (targetNode == null) { return; } //如果這棵二叉樹只有一個節點 if (this.root.left == null && this.root.right == null) { if (root.val == val) { root = null; return; } } //拿到待刪除節點的父節點 Node parent = searchParentNode(val); //如果刪除的葉子節點 if (targetNode.left == null && targetNode.right == null) { //判斷targetNode是parent的左節點還是右節點 if (parent.left != null && parent.left.val == val) { parent.left = null; } else if (parent.right != null && parent.right.val == val) { parent.right = null; } } else if (targetNode.left != null && targetNode.right != null) { // 如果刪除的是帶有兩個葉子節點的節點 //從targetNode的右子樹中找到最小的節點 int temp = searchRightMin(targetNode.right); targetNode.val = temp; }else { //待刪除節點有一個分支 //如果待刪除的節點有左節點 if (targetNode.left !=null){ //待刪除的是根節點 if (parent == null){ this.root = targetNode.left; }else { //待刪除的節點是左節點 if (parent.left!=null && parent.left.val == val){ parent.left = targetNode.left; }else if(parent.right!=null && parent.right.val == val){ // 待刪除的節點是右節點 parent.right = targetNode.left; } } }else { //待刪除的節點有有分支 if (parent == null){ this.root = targetNode.right; }else { if (parent.left!=null && parent.left.val == val){ parent.left = targetNode.right; }else if (parent.right!=null && parent.right.val == val){ parent.right = targetNode.right; } } } } } } } class Node { int val; Node left; Node right; public Node(int val) { this.val = val; } @Override public String toString() { return "Node{" + "val=" + val + '}'; } //查詢待刪除節點的父節點 public Node searchParentNode(int val) { if ((this.left != null && this.left.val == val) || (this.right != null && this.right.val == val)) { return this; } else { if (this.val > val && this.left != null) { return this.left.searchParentNode(val); } else if (this.val <= val && this.right != null) { return this.right.searchParentNode(val); } else { return null; } } } //查詢到待刪除的節點 public Node serachNode(int val) { if (this.val == val) { return this; } else if (this.val > val) { if (this.left != null) { return this.left.serachNode(val); } else { return null; } } else { if (this.right != null) { return this.right.serachNode(val); } else { return null; } } } //新增節點 public void addNode(Node node) { if (this.val > node.val) { //需要掛載到左邊 if (this.left == null) { this.left = node; } else { this.left.addNode(node); } } else { if (this.right == null) { this.right = node; } else { this.right.addNode(node); } } } //中序遍歷 public void midOrder() { if (this.left != null) { this.left.midOrder(); } System.out.println(this.val); if (this.right != null) { this.right.midOrder(); } } }