0 課程地址
https://coding.imooc.com/lesson/207.html#mid=13474
1 重點關注
1.1 刪除最小值代碼草圖
1.2 二分搜索樹 查找 刪除 最小 最大 元素代碼實現
見3.1
2 課程內容
3 Coding
3.1 二分搜索樹 刪除最小元素和刪除最大元素
- 關鍵代碼 查詢最小元素 查詢最大元素
/** * 7.1 查詢最小的元素 * @author weidoudou * @date 2022/11/8 14:30 * @return E **/ public E findMin(){ if(size==0){ throw new IllegalArgumentException("二叉樹爲空,無最小元素"); } return findMin(root); } private E findMin(Node node){ //1 終止條件 if(node.left==null){ return node.e; } //2 遞歸 return findMin(node.left); } /** * 7.2 查詢最大的元素 * @author weidoudou * @date 2022/11/8 14:30 * @return E **/ public E findMax(){ if(size==0){ throw new IllegalArgumentException("二叉樹爲空,無最大元素"); } return findMax(root); } private E findMax(Node node){ //1 終止條件 if(node.right==null){ return node.e; } //2 遞歸 return findMax(node.right); }
- 關鍵代碼 刪除最小元素 刪除最大元素
/** * 7.3 刪除最小元素 * @author weidoudou * @date 2022/11/8 15:43 * @return void **/ public E removMin(){ E e = findMin(); //這裏好好思考下,爲什麼要加上root = //因爲極端情況,最小值爲根節點,不加這個的話,導致第一次刪除後root不變,詳見6-11節代碼草圖 root = removMin(root); return e; } private Node removMin(Node node){ //終止條件 if(node.left==null){ Node rightNode = node.right; node.right = null; size--; return rightNode; } //遞歸 node.left = removMin(node.left); return node; } /** * 7.4 刪除最大元素 * @author weidoudou * @date 2022/11/8 15:43 * @return void **/ public E removMax(){ E e = findMax(); removMax(root); return e; } private Node removMax(Node node){ //終止條件 if(node.right==null){ Node leftNode = node.left; node.left = null; size--; return leftNode; } //遞歸 node.right = removMax(node.right); return node; }
- 全量代碼:
package com.company; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; public class BST2<E extends Comparable> { //1 內部類 private class Node{ //二叉樹特有屬性 private Node left,right; private E e; private Node(E e){ this.e = e; this.left = null; this.right = null; } } private int size; private Node root; public BST2(){ this.size = 0; this.root = null; } /** * 定義基本方法 getSize * @author weidoudou * @date 2022/11/3 12:57 * @return int **/ public int getSize(){ return size; } /** *查詢是否爲空 * @author weidoudou * @date 2022/11/3 12:58 * @return boolean **/ public boolean isEmpty(){ return size == 0; } //2 循環添加元素,把null也看作節點 public void add(E e){ root = add(e,root); } //3 遞歸,添加元素 public Node add(E e,Node root){ //3.1 終止條件 if(root==null){ size++; return new Node(e); } //3.2 遞歸 //3.2.1 遞歸左孩子 if(e.compareTo(root.e)<0){ root.left = add(e,root.left); } //3.2.2 遞歸右孩子 if(e.compareTo(root.e)>0){ root.right = add(e,root.right); } //點睛之筆 return root; } /** * 二分搜索樹 是否包含元素e * @author weidoudou * @date 2022/11/4 9:55 * @param e 請添加參數描述 * @return boolean **/ public boolean contains(E e){ return contains(e,root); } /** * 二分搜索樹查詢 遞歸 * @author weidoudou * @date 2022/11/4 9:57 * @param e 請添加參數描述 * @param node 請添加參數描述 * @return boolean **/ private boolean contains(E e,Node node){ //終止條件 if(node == null){ return false; } if(e.compareTo(node.e)==0){ return true; } //遞歸條件 if(e.compareTo(node.e)<0){ return contains(e,node.left); }else{ return contains(e,node.right); } } /** * 4 二分搜索樹,前序遍歷 顧名思義,先遍歷根節點,再遍歷左節點,最後遍歷右節點 * @author weidoudou * @date 2022/11/5 14:54 * @return null **/ public boolean preOrder(){ preOrder(root); return false; } //前序遍歷 遞歸 private void preOrder(Node node){ //終止條件 if(node==null){ return; } //遞歸 System.out.println(node.e);//1 preOrder(node.left); preOrder(node.right); } /** * 前序遍歷非遞歸寫法 用棧的方法實現 while 代替遞歸 * @author weidoudou * @date 2022/11/8 9:57 * * @return*/ public boolean preOrderNR(){ Stack<Node> stack = new Stack<>(); stack.push(root); while(!stack.isEmpty()){ Node cur = stack.peek(); stack.pop(); System.out.println(cur.e); if(cur.right!=null){ stack.push(cur.right); } if(cur.left!=null){ stack.push(cur.left); } } return false; } /** * 二分搜索樹廣度遍歷 * @author weidoudou * @date 2022/11/8 11:23 * @return boolean **/ public boolean levelOrder(){ Queue<Node> queue = new LinkedList<>(); queue.add(root); while (queue.peek()!=null){ Node cur = queue.peek(); System.out.println(cur.e); queue.remove(); if(cur.left!=null){ queue.add(cur.left); } if(cur.right!=null){ queue.add(cur.right); } } return false; } /** * 5 二分搜索樹,中序遍歷 顧名思義,先遍歷左節點,再遍歷根節點,最後遍歷右節點 * @author weidoudou * @date 2022/11/5 14:54 * @return null **/ public boolean inOrder(){ inOrder(root); return false; } //前序遍歷 遞歸 private void inOrder(Node node){ //終止條件 if(node==null){ return; } //遞歸 inOrder(node.left); System.out.println(node.e);//1 inOrder(node.right); } /** * 6 二分搜索樹,後序遍歷 顧名思義,先遍歷左節點,再遍歷右節點,最後遍歷根節點 * @author weidoudou * @date 2022/11/5 14:54 * @return null **/ public boolean postOrder(){ postOrder(root); return false; } //前序遍歷 遞歸 private void postOrder(Node node){ //終止條件 if(node==null){ return; } //遞歸 postOrder(node.left); postOrder(node.right); System.out.println(node.e);//1 } /** * 基於前序遍歷完成toString打印 * @author weidoudou * @date 2022/11/5 15:20 * @return java.lang.String **/ @Override public String toString() { final StringBuffer sb = new StringBuffer(); generate(root,0); return sb.toString(); } private void generate(Node node, int depth){ generate(depth); //1 終止條件 if(node==null){ System.out.println("null"); return; } //2 遞歸條件 System.out.println(node.e); depth++; generate(node.left,depth); generate(node.right,depth); } private void generate(int depth){ for(int i = 0;i<depth;i++){ System.out.print("=="); } } /** * 7.1 查詢最小的元素 * @author weidoudou * @date 2022/11/8 14:30 * @return E **/ public E findMin(){ if(size==0){ throw new IllegalArgumentException("二叉樹爲空,無最小元素"); } return findMin(root); } private E findMin(Node node){ //1 終止條件 if(node.left==null){ return node.e; } //2 遞歸 return findMin(node.left); } /** * 7.2 查詢最大的元素 * @author weidoudou * @date 2022/11/8 14:30 * @return E **/ public E findMax(){ if(size==0){ throw new IllegalArgumentException("二叉樹爲空,無最大元素"); } return findMax(root); } private E findMax(Node node){ //1 終止條件 if(node.right==null){ return node.e; } //2 遞歸 return findMax(node.right); } /** * 7.3 刪除最小元素 * @author weidoudou * @date 2022/11/8 15:43 * @return void **/ public E removMin(){ E e = findMin(); //這裏好好思考下,爲什麼要加上root = //因爲極端情況,最小值爲根節點,不加這個的話,導致第一次刪除後root不變,詳見本節代碼草圖 root = removMin(root); return e; } private Node removMin(Node node){ //終止條件 if(node.left==null){ Node rightNode = node.right; node.right = null; size--; return rightNode; } //遞歸 node.left = removMin(node.left); return node; } /** * 7.4 刪除最大元素 * @author weidoudou * @date 2022/11/8 15:43 * @return void **/ public E removMax(){ E e = findMax(); removMax(root); return e; } private Node removMax(Node node){ //終止條件 if(node.right==null){ Node leftNode = node.left; node.left = null; size--; return leftNode; } //遞歸 node.right = removMax(node.right); return node; } }
- 測試類:
/** * 刪除最小元素測試 * @author weidoudou * @date 2022/11/8 16:06 * @param args 請添加參數描述 * @return void **/ public static void main(String[] args) { BST2<Integer> bst2 = new BST2<>(); int[] nums = {0,6,3,9,1,4,2}; //生成隨機數 for(int i = 0;i<nums.length;i++){ bst2.add(nums[i]); } for(int i = 0;i<10;i++){ Integer val = new Random().nextInt(10); bst2.add(val); } // System.out.println(bst2.inOrder()); System.out.println(bst2); //查出最小元素 //System.out.println(bst2.findMin()); ArrayList<Integer> arrayList = new ArrayList<>(); while (!bst2.isEmpty()){ arrayList.add(bst2.removMin()); } System.out.println(arrayList); } /** * 刪除最大元素測試 * @author weidoudou * @date 2022/11/8 16:06 * @param args 請添加參數描述 * @return void **/ public static void main(String[] args) { BST2<Integer> bst2 = new BST2<>(); int[] nums = {0,6,3,9,1,4,2}; //生成隨機數 for(int i = 0;i<nums.length;i++){ bst2.add(nums[i]); } for(int i = 0;i<10;i++){ Integer val = new Random().nextInt(10); bst2.add(val); } // System.out.println(bst2.inOrder()); System.out.println(bst2); //查出最小元素 //System.out.println(bst2.findMin()); ArrayList<Integer> arrayList = new ArrayList<>(); while (!bst2.isEmpty()){ arrayList.add(bst2.removMax()); } System.out.println(arrayList); }
- 測試結果 刪除最小元素:
0 ==null ==6 ====3 ======1 ========null ========2 ==========null ==========null ======4 ========null ========5 ==========null ==========null ====9 ======null ======null [0, 1, 2, 3, 4, 5, 6, 9] Process finished with exit code 0
- 測試結果 刪除最大元素:
0 ==null ==6 ====3 ======1 ========null ========2 ==========null ==========null ======4 ========null ========null ====9 ======null ======null [9, 6, 4, 3, 2, 1, 0] Process finished with exit code 0