最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)二分搜索樹(shù)的示例代碼

 更新時(shí)間:2022年03月17日 11:32:24   作者:愛(ài)干飯的猿  
二分搜索樹(shù)是一顆二叉樹(shù),二分搜索樹(shù)每個(gè)節(jié)點(diǎn)的左子樹(shù)的值都小于該節(jié)點(diǎn)的值,每個(gè)節(jié)點(diǎn)右子樹(shù)的值都大于該節(jié)點(diǎn)的值。本文將利用Java實(shí)現(xiàn)二分搜索樹(shù),需要的可以參考一下

1.概念

a.是個(gè)二叉樹(shù)(每個(gè)節(jié)點(diǎn)最多有兩個(gè)子節(jié)點(diǎn))

b.對(duì)于這棵樹(shù)中的節(jié)點(diǎn)的節(jié)點(diǎn)值

左子樹(shù)中的所有節(jié)點(diǎn)值 < 根節(jié)點(diǎn) < 右子樹(shù)的所有節(jié)點(diǎn)值

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

最大特點(diǎn):也是判斷是否是搜索樹(shù)的方法

對(duì)該樹(shù)進(jìn)行中序遍歷,就可以得到一個(gè)升序集合0 1 2 3 4 5 6 7 8 9

在一個(gè)有序區(qū)間上進(jìn)行二分查找的時(shí)間復(fù)雜度? logn不斷將集合/2/2 / 2 ==1為止logN

logN =》聯(lián)想到"樹(shù)"

2.重點(diǎn)操作

當(dāng)刪除58時(shí),此節(jié)點(diǎn)左右子樹(shù)都不為空

Hibbard Deletion 1962

在BST中刪除一個(gè)左右子樹(shù)都存在的節(jié)點(diǎn)

找到當(dāng)前以58為根節(jié)點(diǎn)的前驅(qū)或者后繼節(jié)點(diǎn)作為刪除后的新節(jié)點(diǎn)

前驅(qū):在以58為根的BST中最后一個(gè)小于58的節(jié)點(diǎn)->53

后繼:在以58為根的BST中第一個(gè)大于58的節(jié)點(diǎn)->59

當(dāng)我們使用后繼節(jié)點(diǎn)時(shí),先連removeMin(root.right),在連root.left

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

3.完整代碼

import java.util.NoSuchElementException;
 
/**
 * 基于整型的
 * 普通的二分搜索樹(shù)
 */
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中插入一個(gè)新的結(jié)點(diǎn)val
     * @param val
     */
    public void add(int val){
        root = add(root,val);
    }
 
    private TreeNode add(TreeNode root, int val) {
        if(root == null){
            //創(chuàng)建一個(gè)新節(jié)點(diǎn)
            TreeNode newNode = new TreeNode(val);
            size++;
            return newNode;
        }
        //左子樹(shù)插入
        if(val < root.val){
            root.left = add(root.left,val);
        }
        //右子樹(shù)插入
        if(val > root.val){
            root.right = add(root.right,val);
        }
        return root;
    }
 
    /**
     * 判斷當(dāng)前以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){
            //遞歸左子樹(shù)查找
            return contains(root.left,val);
        }else{
            //遞歸右子樹(shù)查找
            return contains(root.right,val);
        }
    }
 
    /**
     * 找到最小值
     * @return
     */
    public int findMin(){
        //判空
        if(root == null){
            //拋出一個(gè)空指針異常
            throw new NoSuchElementException("root is empty! cannot find min");
        }
        TreeNode minNode = findMin(root);
        return minNode.val;
    }
 
    private TreeNode findMin(TreeNode root) {
        //當(dāng)此節(jié)點(diǎn)左子樹(shù)為空,說(shuō)明此節(jié)點(diǎn)是最小值
        if(root.left == null){
            return root;
        }
        //遞歸訪問(wèn)左子樹(shù)
        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) {
        //當(dāng)此節(jié)點(diǎn)右子樹(shù)為空,說(shuō)明此節(jié)點(diǎn)是最大值
        if(root.right == null){
            return root;
        }
        //遞歸訪問(wèn)右子樹(shù)
        return findMax(root.right);
    }
 
    /**
     * 在當(dāng)前BST中刪除最小值節(jié)點(diǎn),返回刪除的最小值
     * @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;
            //找到最小值,刪除節(jié)點(diǎn)
            root = root.left = null;
            size--;
            return right;
        }
        root.left = removeMin(root.left);
        return root;
    }
 
    /**
     * 在當(dāng)前BST中刪除最大值節(jié)點(diǎn),返回刪除的最大值
     * @return
     */
    public int removeMax(){
        int max = findMax();
        root = removeMax(root);
        return max;
    }
 
    //在當(dāng)前以root為根的BST中刪除最小值所在的節(jié)點(diǎn),返回刪除后的樹(shù)根
    private TreeNode removeMax(TreeNode root) {
        if(root.right == null){
            TreeNode right = root.right;
            //找到最大值,刪除節(jié)點(diǎn)
            root = root.right = null;
            size--;
            return right;
        }
        root.right = findMax(root.right);
        return root;
    }
 
    /**
     * 在當(dāng)前以root為根節(jié)點(diǎn)的BST中刪除值為val的節(jié)點(diǎn)
     * 返回刪除后的新的根節(jié)點(diǎn)
     * @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 {
            //此時(shí)value == root.value
            if(root.left == null){
                //刪除最小數(shù)
                TreeNode right = root.right;
                root = root.right = null;
                size--;
                return right;
            }
            if(root.right == null){
                //刪除最大數(shù)
                TreeNode left = root.left;
                root = root.left =null;
                size--;
                return left;
            }
            //找到當(dāng)前該刪除節(jié)點(diǎn)的前驅(qū)或者后繼節(jié)點(diǎn)作為刪除后的新節(jié)點(diǎn)
            //當(dāng)我們使用后繼節(jié)點(diǎn)時(shí),先連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();
    }
 
    //直觀打印,可以看到樹(shù)的深度
    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();
    }
}

到此這篇關(guān)于Java實(shí)現(xiàn)二分搜索樹(shù)的示例代碼的文章就介紹到這了,更多相關(guān)Java二分搜索樹(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 通過(guò)反射遍歷所有字段修改值的實(shí)例代碼

    java 通過(guò)反射遍歷所有字段修改值的實(shí)例代碼

    這篇文章主要介紹了java 通過(guò)反射遍歷所有字段修改值,通過(guò)java 的反射,遍歷所有字段,進(jìn)行一個(gè)判斷,取出來(lái)的值是帶有圖片鏈接的,進(jìn)行操作,省去了很多代碼,理解也很容易,下面跟隨小編看下實(shí)例代碼吧
    2021-05-05
  • java彈幕小游戲1.0版本

    java彈幕小游戲1.0版本

    這篇文章主要為大家詳細(xì)介紹了java彈幕小游戲1.0版本,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Spring?Boot在啟動(dòng)時(shí)執(zhí)行一次的功能實(shí)現(xiàn)

    Spring?Boot在啟動(dòng)時(shí)執(zhí)行一次的功能實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于Spring?Boot在啟動(dòng)時(shí)執(zhí)行一次的功能實(shí)現(xiàn),在實(shí)習(xí)過(guò)程中,有時(shí)候會(huì)遇到一些項(xiàng)目啟動(dòng)初始化的需求,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • 一文詳解Java Netty中的Constant類(lèi)

    一文詳解Java Netty中的Constant類(lèi)

    這篇文章主要介紹了Constants類(lèi)即常量類(lèi)是將一些常用的變量集合到一個(gè)地方的類(lèi),文中有詳細(xì)的代碼示例,感興趣的同學(xué)可以參考一下
    2023-05-05
  • Java實(shí)現(xiàn)文件圖片的預(yù)覽和下載功能

    Java實(shí)現(xiàn)文件圖片的預(yù)覽和下載功能

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)文件圖片的預(yù)覽和下載功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • 高并發(fā)環(huán)境下安全修改同一行數(shù)據(jù)庫(kù)數(shù)據(jù)的策略分享

    高并發(fā)環(huán)境下安全修改同一行數(shù)據(jù)庫(kù)數(shù)據(jù)的策略分享

    隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,越來(lái)越多的應(yīng)用需要在高并發(fā)環(huán)境中運(yùn)行,數(shù)據(jù)庫(kù)的并發(fā)控制成為了業(yè)務(wù)的關(guān)鍵,本文將介紹如何在高并發(fā)情況下,安全地修改數(shù)據(jù)庫(kù)中的同一行數(shù)據(jù),需要的可以參考一下
    2023-06-06
  • 全網(wǎng)最詳細(xì)Hutool工具詳解

    全網(wǎng)最詳細(xì)Hutool工具詳解

    Hutool的目標(biāo)是使用一個(gè)工具方法代替一段復(fù)雜代碼,從而最大限度的避免“復(fù)制粘貼”代碼的問(wèn)題,徹底改變我們寫(xiě)代碼的方式。這篇文章主要介紹了全文最詳細(xì)Hutool工具詳解,需要的朋友可以參考下
    2021-12-12
  • MyBatis查詢結(jié)果resultType返回值類(lèi)型的說(shuō)明

    MyBatis查詢結(jié)果resultType返回值類(lèi)型的說(shuō)明

    這篇文章主要介紹了MyBatis查詢結(jié)果resultType返回值類(lèi)型的說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • mybatis 加載配置文件的方法(兩種方式)

    mybatis 加載配置文件的方法(兩種方式)

    這篇文章主要介紹了mybatis 加載配置文件的方法,通過(guò)實(shí)例代碼給大家介紹了mybatis 加載配置文件的兩種方式,需要的朋友可以參考下
    2017-12-12
  • Intellij IDEA連接Navicat數(shù)據(jù)庫(kù)的方法

    Intellij IDEA連接Navicat數(shù)據(jù)庫(kù)的方法

    這篇文章主要介紹了Intellij IDEA連接Navicat數(shù)據(jù)庫(kù)的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借價(jià)值,需要的朋友可以參考下
    2021-03-03

最新評(píng)論

伊川县| 庄河市| 宁陵县| 新田县| 肃宁县| 商丘市| 仁寿县| 尖扎县| 平阳县| 彭水| 长丰县| 宝清县| 连山| 辽中县| 都兰县| 临清市| 德阳市| 奇台县| 彭州市| 隆子县| 婺源县| 行唐县| 海南省| 安庆市| 临安市| 海原县| 濮阳县| 宿松县| 武功县| 于都县| 开原市| 江津市| 景东| 罗山县| 余庆县| 内乡县| 西贡区| 沁水县| 大安市| 简阳市| 囊谦县|