亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java如何實現二分搜索樹

發布時間:2022-03-17 15:06:34 來源:億速云 閱讀:131 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關Java如何實現二分搜索樹,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1.概念

a.是個二叉樹(每個節點最多有兩個子節點)

b.對于這棵樹中的節點的節點值

左子樹中的所有節點值 < 根節點 < 右子樹的所有節點值

二分搜索樹中一般不考慮值相等的情況(元素不重復)JDK中的搜索樹就不存在相同的值(TreeMap-key)

Java如何實現二分搜索樹

最大特點:也是判斷是否是搜索樹的方法

對該樹進行中序遍歷,就可以得到一個升序集合0 1 2 3 4 5 6 7 8 9

在一個有序區間上進行二分查找的時間復雜度? logn不斷將集合/2/2 / 2 ==1為止logN

logN =》聯想到"樹"

2.重點操作

Java如何實現二分搜索樹

當刪除58時,此節點左右子樹都不為空

Hibbard Deletion 1962

在BST中刪除一個左右子樹都存在的節點

找到當前以58為根節點的前驅或者后繼節點作為刪除后的新節點

前驅:在以58為根的BST中最后一個小于58的節點->53

后繼:在以58為根的BST中第一個大于58的節點->59

當我們使用后繼節點時,先連removeMin(root.right),在連root.left

TreeNode successor = findMin(root.right);
successor.right = removeMin(root.right);
successor.left = root.left;

3.完整代碼

import java.util.NoSuchElementException;
 
/**
 * 基于整型的
 * 普通的二分搜索樹
 */
public class BST {
 
    private class TreeNode{
        private int val;
        private TreeNode left;
        private TreeNode right;
 
        public TreeNode(int val) {
            this.val = val;
        }
    }
 
    private int size;
    private TreeNode root;
 
    /**
     * 向以root為根的BST中插入一個新的結點val
     * @param val
     */
    public void add(int val){
        root = add(root,val);
    }
 
    private TreeNode add(TreeNode root, int val) {
        if(root == null){
            //創建一個新節點
            TreeNode newNode = new TreeNode(val);
            size++;
            return newNode;
        }
        //左子樹插入
        if(val < root.val){
            root.left = add(root.left,val);
        }
        //右子樹插入
        if(val > root.val){
            root.right = add(root.right,val);
        }
        return root;
    }
 
    /**
     * 判斷當前以root為根的BST中是否包含了val
     * @param val
     * @return
     */
    public boolean contains(int val){
        return contains(root,val);
    }
 
    private boolean contains(TreeNode root, int val) {
        if(root == null){
            return false;
        }
        if(val == root.val){
            //找到了
            return true;
        }else if(val < root.val){
            //遞歸左子樹查找
            return contains(root.left,val);
        }else{
            //遞歸右子樹查找
            return contains(root.right,val);
        }
    }
 
    /**
     * 找到最小值
     * @return
     */
    public int findMin(){
        //判空
        if(root == null){
            //拋出一個空指針異常
            throw new NoSuchElementException("root is empty! cannot find min");
        }
        TreeNode minNode = findMin(root);
        return minNode.val;
    }
 
    private TreeNode findMin(TreeNode root) {
        //當此節點左子樹為空,說明此節點是最小值
        if(root.left == null){
            return root;
        }
        //遞歸訪問左子樹
        return findMin(root.left);
    }
 
    /**
     * 找到最大值
     * @return
     */
    public int findMax(){
        //判空
        if(root == null){
            throw new NoSuchElementException("root is empty! cannot find max");
        }
        TreeNode maxNode = findMax(root);
        return maxNode.val;
    }
 
    private TreeNode findMax(TreeNode root) {
        //當此節點右子樹為空,說明此節點是最大值
        if(root.right == null){
            return root;
        }
        //遞歸訪問右子樹
        return findMax(root.right);
    }
 
    /**
     * 在當前BST中刪除最小值節點,返回刪除的最小值
     * @return
     */
    public int removeMin(){
        int min =findMin();
        root = removeMin(root);
        return min;
    }
 
    private TreeNode removeMin(TreeNode root) {
        if(root.left == null){
            TreeNode right = root.right;
            //找到最小值,刪除節點
            root = root.left = null;
            size--;
            return right;
        }
        root.left = removeMin(root.left);
        return root;
    }
 
    /**
     * 在當前BST中刪除最大值節點,返回刪除的最大值
     * @return
     */
    public int removeMax(){
        int max = findMax();
        root = removeMax(root);
        return max;
    }
 
    //在當前以root為根的BST中刪除最小值所在的節點,返回刪除后的樹根
    private TreeNode removeMax(TreeNode root) {
        if(root.right == null){
            TreeNode right = root.right;
            //找到最大值,刪除節點
            root = root.right = null;
            size--;
            return right;
        }
        root.right = findMax(root.right);
        return root;
    }
 
    /**
     * 在當前以root為根節點的BST中刪除值為val的節點
     * 返回刪除后的新的根節點
     * @return
     */
    public void removeValue(int value){
        root = removeValue(root,value);
    }
 
    private TreeNode removeValue(TreeNode root, int value) {
        if(root == null){
            throw new NoSuchElementException("root is empty! cannot find remove");
        }else if(value < root.val){
            root.left = removeValue(root.left,value);
            return root;
        }else if(value > root.val){
            root.right = removeValue(root.right,value);
            return root;
        }else {
            //此時value == root.value
            if(root.left == null){
                //刪除最小數
                TreeNode right = root.right;
                root = root.right = null;
                size--;
                return right;
            }
            if(root.right == null){
                //刪除最大數
                TreeNode left = root.left;
                root = root.left =null;
                size--;
                return left;
            }
            //找到當前該刪除節點的前驅或者后繼節點作為刪除后的新節點
            //當我們使用后繼節點時,先連removeMin(root.right),在連root.left
            TreeNode successor = findMin(root.right);
            successor.right = removeMin(root.right);
            successor.left = root.left;
            return successor;
        }
    }
 
 
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        generateBSTString(root,0,sb);
        return sb.toString();
    }
 
    //直觀打印,可以看到樹的深度
    private void generateBSTString(TreeNode root, int height, StringBuilder sb) {
        if(root == null){
            sb.append(generateHeightString(height)).append("NULL\n");
            return;
        }
        sb.append(generateHeightString(height)).append(root.val).append("\n");
        generateBSTString(root.left,height+1,sb);
        generateBSTString(root.right,height+1,sb);
    }
 
    private String generateHeightString(int height) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < height; i++) {
            sb.append("--");
        }
        return sb.toString();
    }
}

關于“Java如何實現二分搜索樹”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

横峰县| 七台河市| 军事| 商南县| 东乡| 大关县| 宣化县| 苏尼特左旗| 从化市| 木里| 五台县| 龙川县| 义马市| 黑河市| 大化| 平罗县| 黄陵县| 海门市| 中宁县| 高邑县| 扶沟县| 民和| 宾川县| 景德镇市| 秦安县| 河间市| 柘荣县| 芜湖市| 年辖:市辖区| 正阳县| 舞钢市| 姚安县| 曲靖市| 都匀市| 凌海市| 南康市| 泾阳县| 金阳县| 临澧县| 鄱阳县| 岚皋县|