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

Java二叉樹(shù)查詢?cè)砩钊敕治鲋v解

 更新時(shí)間:2022年11月22日 14:53:00   作者:wei_shuo  
這篇文章主要介紹了Java二叉樹(shù)查詢?cè)恚娌檎覙?shù),又稱二叉排序樹(shù),亦稱二叉搜索樹(shù),是數(shù)據(jù)結(jié)構(gòu)中的一類。在一般情況下,查找效率比鏈表結(jié)構(gòu)要高

二叉查詢樹(shù)

概述

二叉樹(shù)(Binary tree)是樹(shù)形結(jié)構(gòu)的一個(gè)重要類型。許多實(shí)際問(wèn)題抽象出來(lái)的數(shù)據(jù)結(jié)構(gòu)往往是二叉樹(shù)形式,即使是一般的樹(shù)也能簡(jiǎn)單地轉(zhuǎn)換為二叉樹(shù),而且二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)及其算法都較為簡(jiǎn)單,因此二叉樹(shù)顯得特別重要。二叉樹(shù)特點(diǎn)是每個(gè)節(jié)點(diǎn)最多只能有兩棵子樹(shù),且有左右之分

特點(diǎn)

樹(shù)同時(shí)具有數(shù)組查詢的效率、鏈表增刪、改的性能

右子樹(shù)的結(jié)點(diǎn)比左子樹(shù)的節(jié)點(diǎn)大

查找法

搜索的數(shù)字如果比節(jié)點(diǎn)大則往右搜索,搜索的數(shù)字如果比節(jié)點(diǎn)小則往左搜索

結(jié)點(diǎn)實(shí)現(xiàn)原理

插入實(shí)現(xiàn)原理

int[] arrs = {5,2,1,4,3,9,7,6,8};

如果樹(shù)是空樹(shù),插入節(jié)點(diǎn)就直接放入到根結(jié)點(diǎn)

如果樹(shù)不是空樹(shù),則插入的數(shù)字于根結(jié)點(diǎn)的數(shù)字進(jìn)行比較

如果插入的值小于于結(jié)點(diǎn)的數(shù)字,則往左子樹(shù)插入

  • 如果左子結(jié)點(diǎn)沒(méi)有元素就插入到左子結(jié)點(diǎn)中
  • 如果左子結(jié)點(diǎn)有元素,就可以設(shè)計(jì)一個(gè)引用(游標(biāo))指向左子節(jié)點(diǎn),并且再次和待插入的執(zhí)行左子結(jié)點(diǎn)進(jìn)行比較,直到找到插入的位置

如果插入的值大于結(jié)點(diǎn)的數(shù)字,則往右子樹(shù)插入

  • 判斷右子結(jié)點(diǎn)是否存在值,如果不存在則直接插入
  • 判斷右子結(jié)點(diǎn)是否存在值,如果存在則通過(guò)一個(gè)引用指向右子結(jié)點(diǎn)繼續(xù)和待插入的值進(jìn)行比較,直到找到插入的位置

總結(jié):

  • 小往左,大往右
  • 左子數(shù)永遠(yuǎn)小于右子樹(shù)

遍歷實(shí)現(xiàn)原理

中序遍歷:左—根—右

通過(guò)中序遍歷就可以將二叉樹(shù)查找樹(shù)的進(jìn)行順序輸出

總結(jié):

始終貫徹左—根—右的原則、由內(nèi)層向外層拆分

int[] arrs = {1,2,3,4,5,6,7,8,9};

刪除實(shí)現(xiàn)原理

提供一個(gè)待刪除的結(jié)點(diǎn)的值,根據(jù)值從二叉查找樹(shù)找到需要?jiǎng)h除的結(jié)點(diǎn)

找到待刪除結(jié)點(diǎn)的父類結(jié)點(diǎn),并且要根據(jù)待刪除結(jié)點(diǎn)在父類結(jié)點(diǎn)的左右子樹(shù)的位置,設(shè)置為null進(jìn)行刪除

需要考慮結(jié)點(diǎn)的三種情況

情況1:待刪除的結(jié)點(diǎn)沒(méi)有子結(jié)點(diǎn)

直接讓父類結(jié)點(diǎn)的對(duì)應(yīng)目標(biāo)結(jié)點(diǎn)引用設(shè)置為null即可

情況2:待刪除的結(jié)點(diǎn)有一個(gè)子節(jié)點(diǎn)

將待刪除的父類結(jié)點(diǎn)對(duì)應(yīng)子節(jié)點(diǎn)的引用指向待刪除結(jié)點(diǎn)的子節(jié)點(diǎn)

情況3:待刪除的結(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn) 從左子樹(shù)中找到最大的結(jié)點(diǎn)進(jìn)行刪除,并且將最大的結(jié)點(diǎn)的值放入到待刪除結(jié)點(diǎn)從右子樹(shù)中找到最小的結(jié)點(diǎn)進(jìn)行刪除,并且將最小的結(jié)點(diǎn)的值放入(替換)到待刪除結(jié)點(diǎn)

(上述兩種刪除方法:需要將待刪除結(jié)點(diǎn)指向新創(chuàng)建(替換后的)的結(jié)點(diǎn),并且將新的結(jié)點(diǎn)(替換后的)的左右結(jié)點(diǎn)指向待刪除的左右子樹(shù)的結(jié)點(diǎn))

刪除的結(jié)點(diǎn)是根節(jié)點(diǎn)的情況

情況1:根節(jié)點(diǎn)沒(méi)有子節(jié)點(diǎn),直接將根結(jié)點(diǎn)指向null

情況2:根結(jié)點(diǎn)有一個(gè)子節(jié)點(diǎn),則根結(jié)點(diǎn)直接指向子節(jié)點(diǎn)

情況3:根結(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn)

可以從左子樹(shù)中找到最大值刪除結(jié)點(diǎn),然后將最大值覆蓋(替換)根節(jié)點(diǎn)

可以從右子樹(shù)中找到最小值刪除結(jié)點(diǎn),然后將最小值覆蓋(替換)根節(jié)點(diǎn)

結(jié)點(diǎn)插入與遍歷案例

BinarySearchTree類

package Algorithm;
public class BinarySearchTree {
    Node root;  //定義根節(jié)點(diǎn)
    //結(jié)點(diǎn)插入方法
    public void insert(int value) {
        if (root == null) {        //1.如果樹(shù)是空樹(shù),插入節(jié)點(diǎn)就直接放入到根結(jié)點(diǎn)
            root = new Node(value);
        } else {     //如果樹(shù)不是空樹(shù),則插入的數(shù)字于根結(jié)點(diǎn)的數(shù)字進(jìn)行比較
            //2.如果插入的值小于于結(jié)點(diǎn)的數(shù)字,則往左子樹(shù)插入
            Node node = root;     //聲明一個(gè)游標(biāo)結(jié)點(diǎn),開(kāi)始指向根節(jié)點(diǎn)
            while (true) {       //并且再次和待插入的執(zhí)行左子結(jié)點(diǎn)進(jìn)行比較,直到找到插入的位置
                if (value < node.value) {      //如果插入的值小于于結(jié)點(diǎn)的數(shù)字,則往左子樹(shù)插入
                    //2.1如果左子結(jié)點(diǎn)沒(méi)有元素就插入到左子結(jié)點(diǎn)中
                    if (node.left == null) {
                        node.left = new Node(value);
                        break;      //如果找到插入的位置,則跳出while循環(huán)
                    } else {         //如果左子結(jié)點(diǎn)有元素,就可以設(shè)計(jì)一個(gè)引用(游標(biāo))指向左子節(jié)點(diǎn),并且再次和待插入的執(zhí)行左子結(jié)點(diǎn)進(jìn)行比較,直到找到插入的位置
                        //游標(biāo)指向左子節(jié)點(diǎn)
                        node = node.left;
                    }
                } else {      //如果插入的值大于結(jié)點(diǎn)的數(shù)字,則往右子樹(shù)插入
                    //判斷右子結(jié)點(diǎn)是否存在值,如果不存在則直接插入
                    if (node.right == null) {
                        node.right = new Node(value);
                        break;
                    } else {     //判斷右子結(jié)點(diǎn)是否存在值,如果存在則通過(guò)一個(gè)引用指向右子結(jié)點(diǎn)繼續(xù)和待插入的值進(jìn)行比較,直到找到插入的位置
                        //游標(biāo)指向右子節(jié)點(diǎn)
                        node = node.right;
                    }
                }
            }
        }
    }
    //定義左右結(jié)點(diǎn)常量
    public static final int LEFT = 0; //左子節(jié)點(diǎn)
    public static final int RIGHT = 1; //右子節(jié)點(diǎn)
    //結(jié)點(diǎn)查找方法
    public void deleteNode(int value) {
        //定義游標(biāo)從根節(jié)點(diǎn)開(kāi)始查詢
        Node node = root;
        //定義目標(biāo)結(jié)點(diǎn)
        Node target = null;
        //定義目標(biāo)結(jié)點(diǎn)的父類結(jié)點(diǎn)
        Node parent = null;
        //目標(biāo)結(jié)點(diǎn)的類型為,左子節(jié)點(diǎn)或者右子節(jié)點(diǎn)
        int nodeType = 0; //0代表左子節(jié)點(diǎn) 1代表右子節(jié)點(diǎn)

        while (node != null) { //游標(biāo)不為空,如果為空則沒(méi)有子節(jié)點(diǎn),無(wú)法刪除
            if (node.value == value) { //如果目標(biāo)結(jié)點(diǎn)的值和需要?jiǎng)h除結(jié)點(diǎn)的值相同
                //找到結(jié)點(diǎn)
                target = node;
                break;
            } else if (value < node.value) {    //如果值不同,則判斷目標(biāo)結(jié)點(diǎn)值是否小于node結(jié)點(diǎn)
                //保存父類結(jié)點(diǎn)
                parent = node;
                //游標(biāo)指向左子節(jié)點(diǎn)
                node = node.left;
                nodeType = LEFT;
            } else { //如果值不同,且目標(biāo)結(jié)點(diǎn)值大于node結(jié)點(diǎn)
                //保存父類結(jié)點(diǎn)
                parent = node;
                //游標(biāo)指向右子節(jié)點(diǎn)
                node = node.right;
                nodeType = RIGHT;
            }
        }
        //如果沒(méi)找到需要?jiǎng)h除的目標(biāo)結(jié)點(diǎn)
        if (target==null){
            System.out.println("沒(méi)有找到要?jiǎng)h除的結(jié)點(diǎn)");
            return;
        }
        //刪除結(jié)點(diǎn)的三種情況
        if (target.left == null && target.right == null) {   //情況1:待刪除的結(jié)點(diǎn)沒(méi)有子結(jié)點(diǎn)

            if (parent==null){      //刪除的結(jié)點(diǎn)沒(méi)有子結(jié)點(diǎn)
                //將root設(shè)置為null即可
                root=null;
                return;
            }
            //判斷目標(biāo)的結(jié)點(diǎn)是左子節(jié)點(diǎn)還是右子節(jié)點(diǎn)
            if (nodeType == LEFT) {
                //將父類的左子節(jié)點(diǎn)設(shè)置為null
                parent.left = null;
            } else {
                //將父類的右子節(jié)點(diǎn)設(shè)置為null
                parent.right = null;
            }
        } else if (target.left != null && target.right != null) {   //情況2:待刪除的結(jié)點(diǎn)有2個(gè)子節(jié)點(diǎn)
            //兩個(gè)子節(jié)點(diǎn),從target右子樹(shù)查找最小的值
            Node min=target.right;
            //遍歷左子樹(shù)
            while (min.left!=null){
                min = min.left;
            }
            //將最小的結(jié)點(diǎn)進(jìn)行刪除
            deleteNode(min.value);
            //將待刪除的結(jié)點(diǎn)替換成最小的結(jié)點(diǎn)的值
            target.value= min.value;
        }else { //情況3:待刪除的結(jié)點(diǎn)有1個(gè)子節(jié)點(diǎn)
            //刪除結(jié)點(diǎn)是根節(jié)點(diǎn)
            if (parent==null){
                if (target.left!=null){ //判斷是左子節(jié)點(diǎn)還是右子節(jié)點(diǎn)有值
                    root=target.left;   //根節(jié)點(diǎn)=目標(biāo)左子結(jié)點(diǎn)
                }else {
                    root=target.right;  //根節(jié)點(diǎn)=目標(biāo)右子結(jié)點(diǎn)
                }
            }
            //只有一個(gè)子節(jié)點(diǎn)
            if (nodeType==LEFT){    //如果是左子節(jié)點(diǎn)
                if (target.left!=null){
                    //將父類的左子節(jié)點(diǎn),指向待刪除結(jié)點(diǎn)的左子節(jié)點(diǎn)
                    parent.left=target.left;
                }else { //如果是右子節(jié)點(diǎn)
                    //將父類的左子節(jié)點(diǎn),指向待刪除結(jié)點(diǎn)的右子節(jié)點(diǎn)
                    parent.left=target.right;
                }
            }else {
                if (target.right!=null){
                    //將父類的右子節(jié)點(diǎn),指向待刪除結(jié)點(diǎn)的左子節(jié)點(diǎn)
                    parent.right=target.left;
                }else { //如果是右子節(jié)點(diǎn)
                    //將父類的右子節(jié)點(diǎn),指向待刪除結(jié)點(diǎn)的右子節(jié)點(diǎn)
                    parent.right=target.right;
                }
            }
        }
    }
    //實(shí)現(xiàn)中序遍歷
    public void midTraversal(Node node) {
        if (node == null) {  //進(jìn)行判斷結(jié)點(diǎn)不能為空,如果為空則退出
            return;
        } else {     //如果結(jié)點(diǎn)不為null,則執(zhí)行下列遍歷語(yǔ)句
            //首先,遍歷左節(jié)點(diǎn)
            midTraversal(node.left);
            //打印根節(jié)點(diǎn)
            System.out.print(node.value + ",");
            //最后遍歷右子結(jié)點(diǎn)
            midTraversal(node.right);
        }
    }
    //創(chuàng)建一個(gè)結(jié)點(diǎn)類
    public static class Node {
        int value;  //存儲(chǔ)值
        Node left;  //左子樹(shù)
        Node right; //右子樹(shù)
        // 帶參構(gòu)造方法,傳入value賦值
        public Node(int value) {
            this.value = value;
        }
    }
}

TestBST測(cè)試類

package Algorithm;
public class TestBST {
    public static void main(String[] args) {
        int[] arrs = {5, 2, 1, 4, 3, 9, 7, 6, 8};
        //創(chuàng)建二叉查詢樹(shù)
        BinarySearchTree tree = new BinarySearchTree();
        //將數(shù)組中的元素構(gòu)造成二叉查詢樹(shù)
        for (int i = 0; i < arrs.length; i++) {
            tree.insert(arrs[i]);
        }
        //刪除結(jié)點(diǎn)
        tree.deleteNode(20);
        //中序遍歷根結(jié)點(diǎn)
        tree.midTraversal(tree.root);
    }
}

到此這篇關(guān)于Java二叉樹(shù)查詢?cè)砩钊敕治鲋v解的文章就介紹到這了,更多相關(guān)Java二叉樹(shù)查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的@Async異步功能詳解

    Java中的@Async異步功能詳解

    這篇文章主要介紹了Java中的@Async異步功能詳解,@Async注解,可以實(shí)現(xiàn)異步處理的功能,它可以有返回值,或者直接在新線程時(shí)并行執(zhí)行一個(gè)任務(wù),對(duì)于異步來(lái)說(shuō),它的執(zhí)行是有條件的,你需要把異步代碼塊放在單獨(dú)的類里,需要的朋友可以參考下
    2023-11-11
  • Hibernate之環(huán)境搭建及demo分享

    Hibernate之環(huán)境搭建及demo分享

    下面小編就為大家分享一篇Hibernate之環(huán)境搭建及demo,具有很好的參考價(jià)值,希望對(duì)大家有所幫助
    2017-11-11
  • Mybatis-Plus批量插入用法詳解

    Mybatis-Plus批量插入用法詳解

    mybatis-plus的IService接口默認(rèn)提供saveBatch批量插入,也是唯一一個(gè)默認(rèn)批量插入,在數(shù)據(jù)量不是很大的情況下可以直接使用,但這種是一條一條執(zhí)行的效率上會(huì)有一定的瓶頸,今天我們就來(lái)研究研究mybatis-plus中的批量插入
    2023-02-02
  • springboot項(xiàng)目打包鏡像方式以及區(qū)分環(huán)境打包的方法

    springboot項(xiàng)目打包鏡像方式以及區(qū)分環(huán)境打包的方法

    本文主要介紹了springboot項(xiàng)目打包鏡像方式以及區(qū)分環(huán)境打包的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • IDEA SSM整合Redis項(xiàng)目實(shí)例 附源碼

    IDEA SSM整合Redis項(xiàng)目實(shí)例 附源碼

    今天給大家普及IDEA SSM整合Redis項(xiàng)目實(shí)例,包括pom.xml 配置和spring-redis.xml 配置代碼,代碼也很簡(jiǎn)單,通過(guò)項(xiàng)目實(shí)際案例能更好的幫助大家理解,需要的朋友可以參考下
    2021-06-06
  • Java8的Stream()與ParallelStream()的區(qū)別說(shuō)明

    Java8的Stream()與ParallelStream()的區(qū)別說(shuō)明

    這篇文章主要介紹了Java8的Stream()與ParallelStream()的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 使用Feign調(diào)用注解組件(實(shí)現(xiàn)字段賦值功能)

    使用Feign調(diào)用注解組件(實(shí)現(xiàn)字段賦值功能)

    這篇文章主要介紹了使用Feign調(diào)用注解組件(實(shí)現(xiàn)字段賦值功能),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • springboot整合shiro與自定義過(guò)濾器的全過(guò)程

    springboot整合shiro與自定義過(guò)濾器的全過(guò)程

    這篇文章主要給大家介紹了關(guān)于springboot整合shiro與自定義過(guò)濾器以及Shiro中權(quán)限控制的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • jdk7 中HashMap的知識(shí)點(diǎn)總結(jié)

    jdk7 中HashMap的知識(shí)點(diǎn)總結(jié)

    HashMap的原理是老生常談了,不作仔細(xì)解說(shuō)。一句話概括為HashMap是一個(gè)散列表,它存儲(chǔ)的內(nèi)容是鍵值對(duì)(key-value)映射。這篇文章主要總結(jié)了關(guān)于jdk7 中HashMap的知識(shí)點(diǎn),需要的朋友可以參考借鑒,一起來(lái)看看吧。
    2017-01-01
  • JDK14性能管理工具之jstack使用介紹

    JDK14性能管理工具之jstack使用介紹

    jstack工具主要用來(lái)打印java堆棧信息,主要是java的class名字,方法名,字節(jié)碼索引,行數(shù)等信息。這篇文章主要介紹了JDK14性能管理工具之jstack使用介紹,需要的朋友可以參考下
    2020-05-05

最新評(píng)論

延津县| 托克逊县| 文昌市| 明水县| 许昌县| 靖西县| 游戏| 增城市| 昭觉县| 宝鸡市| 乌审旗| 阿城市| 台东县| 丹寨县| 绥宁县| 清水河县| 砀山县| 板桥市| 呈贡县| 常宁市| 新干县| 长子县| 措勤县| 色达县| 池州市| 涞水县| 双流县| 扎鲁特旗| 沾益县| 建德市| SHOW| 万源市| 安新县| 上饶市| 宝鸡市| 东城区| 塔河县| 山东省| 陆良县| 土默特右旗| 南部县|