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

詳解Java?二叉樹(shù)的實(shí)現(xiàn)和遍歷

 更新時(shí)間:2022年03月24日 09:21:31   作者:炒雞辣雞123  
二叉樹(shù)可以簡(jiǎn)單理解為對(duì)于一個(gè)節(jié)點(diǎn)來(lái)說(shuō),最多擁有一個(gè)上級(jí)節(jié)點(diǎn),同時(shí)最多具備左右兩個(gè)下級(jí)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)。本文將詳細(xì)介紹一下Java中二叉樹(shù)的實(shí)現(xiàn)和遍歷,需要的可以參考一下

什么是二叉樹(shù)

簡(jiǎn)單理解為對(duì)于一個(gè)節(jié)點(diǎn)來(lái)說(shuō),最多擁有一個(gè)上級(jí)節(jié)點(diǎn),同時(shí)最多具備左右兩個(gè)下級(jí)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)。

由于很多排序算法都是基于二叉樹(shù)實(shí)現(xiàn)的,多叉樹(shù)也是二叉樹(shù)延伸過(guò)去的,所以二叉樹(shù)的建樹(shù)和遍歷就顯得非常重要。

二叉樹(shù)建樹(shù)

一般情況是給你一個(gè)串,要求讓你以前序,中序,后序的方式建樹(shù)。那么此時(shí)我們就需要首先了解三個(gè)概念:

  • 前序遍歷
  • 中序遍歷
  • 后序遍歷

我們來(lái)看看一棵二叉樹(shù)的結(jié)構(gòu):

0

1 2

3 4 5 6

0就是整個(gè)二叉樹(shù)的根節(jié)點(diǎn),1就是0這個(gè)節(jié)點(diǎn)的左子樹(shù),2就是0這個(gè)節(jié)點(diǎn)的右子樹(shù)。有了這個(gè)知識(shí),我們就可以理解前中后序遍歷這個(gè)位置屬性就是指的根在哪個(gè)位置,前序遍歷就是根在前,所以就是根左子樹(shù)右子樹(shù)的遍歷方式;中序遍歷就是根在中間,所以就是左子樹(shù)根右子樹(shù)的遍歷方式;后序遍歷就是根在最后,所以就是左子樹(shù)右子樹(shù)根的遍歷方式。

遍歷的方式有三種,對(duì)應(yīng)的建樹(shù)方式有已知中序和前序建樹(shù),已知中序和后序建樹(shù),已知前序和后序建樹(shù)三種。

如果我們僅僅是想構(gòu)建一棵二叉平衡樹(shù),可以簡(jiǎn)單使用某一種序列建樹(shù)。用偽代碼表示這三種遍歷方式就是

1.前序遍歷的方式建樹(shù)

new Tree(根節(jié)點(diǎn));
buildTree(左子樹(shù));
buildTree(右子樹(shù));

2.中序遍歷的方式建樹(shù)

buildTree(左子樹(shù));
new Tree(根節(jié)點(diǎn));
buildTree(右子樹(shù));

3.后序遍歷的方式建樹(shù)

buildTree(左子樹(shù));
buildTree(右子樹(shù));
new Tree(根節(jié)點(diǎn));

前序建樹(shù)

我們現(xiàn)在以序列 1, 2, 3, 4, 5, 6, 7, 8, 9 為例,如果是前序建樹(shù)方式,那么二叉樹(shù)的結(jié)構(gòu)應(yīng)該為:

實(shí)現(xiàn)也比較簡(jiǎn)單

package com.chaojilaji.book.tree;

import com.chaojilaji.auto.autocode.utils.Json;

public class Handle {

    /**
     * 前序建樹(shù)
     *
     * @param input
     * @param index
     * @return
     */
    public static Tree buildTreePrologue(int[] input, int index) {
        // TODO: 2022/1/12 根節(jié)點(diǎn)就是當(dāng)前index這個(gè)節(jié)點(diǎn)
        Tree tree = new Tree();
        tree.setValue(input[index]);
        // TODO: 2022/1/12 左右兩個(gè)節(jié)點(diǎn)分別為 2*index-1和2*index+1
        int[] children = new int[]{2 * index + 1, 2 * index + 2};
        if (children[0] < input.length) {
            tree.setLeftChild(buildTreePrologue(input, children[0]));
        }
        if (children[1] < input.length) {
            tree.setRightChild(buildTreePrologue(input, children[1]));
        }
        return tree;
    }


    public static void demo() {
        int[] a = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
        Tree tree = buildTreePrologue(a, 0);
        System.out.println(Json.toJson(tree));

    }

    public static void main(String[] args) {
        demo();
    }
}

執(zhí)行結(jié)果如下:

{
    "value": 1,
    "left_child": {
        "value": 2,
        "left_child": {
            "value": 4,
            "left_child": {
                "value": 8,
                "left_child": null,
                "right_child": null
            },
            "right_child": {
                "value": 9,
                "left_child": null,
                "right_child": null
            }
        },
        "right_child": {
            "value": 5,
            "left_child": null,
            "right_child": null
        }
    },
    "right_child": {
        "value": 3,
        "left_child": {
            "value": 6,
            "left_child": null,
            "right_child": null
        },
        "right_child": {
            "value": 7,
            "left_child": null,
            "right_child": null
        }
    }
}

中序建樹(shù)

以 1,2,3,4,5,6,7序列為例,如果是中序建樹(shù)的方式,那么二叉樹(shù)的結(jié)構(gòu)應(yīng)該為

代碼如下:

package com.chaojilaji.book.tree;

import com.chaojilaji.auto.autocode.utils.Json;
import com.chaojilaji.auto.autocode.utils.MathUtils;

import java.util.LinkedList;
import java.util.Objects;
import java.util.Queue;

public class Handle {

    /**
     * 中序建樹(shù)
     * @param input
     * @param height
     * @param maxHeight
     * @return
     */
    public static Tree buildTree2(Queue<Integer> input, int height, int maxHeight) {
        // TODO: 2022/1/12 根節(jié)點(diǎn)就是當(dāng)前index這個(gè)節(jié)點(diǎn)
        Tree tree = new Tree();

        if (height < maxHeight) {
            tree.setLeftChild(buildTree2(input, height + 1, maxHeight));
        }
        if (!input.isEmpty()) {
            tree.setValue(input.poll());
        }
        if (height < maxHeight) {
            tree.setRightChild(buildTree2(input, height + 1, maxHeight));
        }
        return tree;
    }

    public static void demo() {
        int[] a = new int[]{1, 2, 3, 4, 5, 6, 7};
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < a.length; i++) {
            queue.add(a[i]);
        }
        Integer maxCeng = new Double(Math.ceil(MathUtils.getLogAN(2, a.length + 1))).intValue();
        System.out.println(Json.toJson(buildTree2(queue, 1, maxCeng)));
    }

    public static void main(String[] args) {
        demo();
    }
}

相對(duì)前序建樹(shù)以擴(kuò)展的方式建立二叉樹(shù),中序建樹(shù)由于無(wú)法很好的控制索引,所以這里使用了一個(gè)隊(duì)列來(lái)存儲(chǔ)整個(gè)序列,同時(shí)需要算出以當(dāng)前的節(jié)點(diǎn)數(shù),算出建立一棵二叉平衡樹(shù),最小的深度為多少。然后按照之前給出的偽代碼,按照左根右的方式賦值和遞歸調(diào)用即可。
運(yùn)行的結(jié)果如下:

{
    "value": 4,
    "left_child": {
        "value": 2,
        "left_child": {
            "value": 1,
            "left_child": null,
            "right_child": null
        },
        "right_child": {
            "value": 3,
            "left_child": null,
            "right_child": null
        }
    },
    "right_child": {
        "value": 6,
        "left_child": {
            "value": 5,
            "left_child": null,
            "right_child": null
        },
        "right_child": {
            "value": 7,
            "left_child": null,
            "right_child": null
        }
    }
}

后序建樹(shù)

有了中序遍歷,其實(shí)后序遍歷就非常簡(jiǎn)單了,以序列1,2,3,4,5,6,7為例,建樹(shù)應(yīng)該為

代碼如下:

package com.chaojilaji.book.tree;

import com.chaojilaji.auto.autocode.utils.Json;
import com.chaojilaji.auto.autocode.utils.MathUtils;

import java.util.LinkedList;
import java.util.Objects;
import java.util.Queue;

public class Handle {

    /**
     * 后序建樹(shù)
     *
     * @return
     */
    public static Tree buildTree3(Queue<Integer> input, int height, int maxHeight) {
        // TODO: 2022/1/12 根節(jié)點(diǎn)就是當(dāng)前index這個(gè)節(jié)點(diǎn)
        Tree tree = new Tree();

        if (height < maxHeight) {
            tree.setLeftChild(buildTree3(input, height + 1, maxHeight));
        }

        if (height < maxHeight) {
            tree.setRightChild(buildTree3(input, height + 1, maxHeight));
        }
        if (!input.isEmpty()) {
            tree.setValue(input.poll());
        }
        return tree;
    }

    public static void demo() {
        int[] a = new int[]{1, 2, 3, 4, 5, 6, 7};
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < a.length; i++) {
            queue.add(a[i]);
        }
        Integer maxCeng = new Double(Math.ceil(MathUtils.getLogAN(2, a.length + 1))).intValue();                                                     
        System.out.println(Json.toJson(buildTree3(queue, 1, maxCeng)));

    }

    public static void main(String[] args) {
        demo();
    }


}

通過(guò)分析三個(gè)建樹(shù)方法的代碼你可以發(fā)現(xiàn),其實(shí)本質(zhì)上,根賦值代碼,與調(diào)用左右子樹(shù)建樹(shù)函數(shù)的擺放的位置不同,就早就了這三種不同的算法。

三種建樹(shù)方法對(duì)應(yīng)的三種遍歷方法本質(zhì)區(qū)別也就是打印值語(yǔ)句與調(diào)用左右子樹(shù)打印值函數(shù)的擺放位置不同。如果舉一反三的話,我們可以很容易的得出二叉樹(shù)前中后序遍歷的代碼。那么,請(qǐng)你自己先嘗試一下。

二叉樹(shù)的遍歷

根據(jù)建樹(shù)的經(jīng)驗(yàn),知道,我們只需要寫出一種遍歷方法,那么其他兩種遍歷方式都有了。區(qū)別只不過(guò)是換換打印語(yǔ)句的位置。
對(duì)于前序遍歷,寫法如下:

public static void print1(Tree tree) {
    if (Objects.isNull(tree)) return;
    if (Objects.nonNull(tree.getValue())) {
        System.out.print(tree.getValue());
    }
    if (Objects.nonNull(tree.getLeftChild())) {
        print1(tree.getLeftChild());
    }
    if (Objects.nonNull(tree.getRightChild())) {
        print1(tree.getRightChild());
    }
}

那么我們來(lái)做一個(gè)實(shí)驗(yàn),首先根據(jù)序列1,2,3,4,5,6,7利用前序遍歷構(gòu)建出一棵平衡二叉樹(shù),然后打印出其前序中序后序遍歷的順序。完整的代碼如下:

package com.chaojilaji.book.tree;

import com.chaojilaji.auto.autocode.utils.Json;
import com.chaojilaji.auto.autocode.utils.MathUtils;

import java.util.LinkedList;
import java.util.Objects;
import java.util.Queue;

public class Handle {


    /**
     * 前序建樹(shù)
     *
     * @param input
     * @param index
     * @return
     */
    public static Tree buildTreePrologue(int[] input, int index) {
        // TODO: 2022/1/12 根節(jié)點(diǎn)就是當(dāng)前index這個(gè)節(jié)點(diǎn)
        Tree tree = new Tree();
        tree.setValue(input[index]);
        // TODO: 2022/1/12 左右兩個(gè)節(jié)點(diǎn)分別為 2*index-1和2*index+1
        int[] children = new int[]{2 * index + 1, 2 * index + 2};
        if (children[0] < input.length) {
            tree.setLeftChild(buildTreePrologue(input, children[0]));
        }
        if (children[1] < input.length) {
            tree.setRightChild(buildTreePrologue(input, children[1]));
        }
        return tree;
    }

    /**
     * 中序建樹(shù)
     *
     * @param input
     * @param height
     * @param maxHeight
     * @return
     */
    public static Tree buildTree2(Queue<Integer> input, int height, int maxHeight) {
        // TODO: 2022/1/12 根節(jié)點(diǎn)就是當(dāng)前index這個(gè)節(jié)點(diǎn)
        Tree tree = new Tree();

        if (height < maxHeight) {
            tree.setLeftChild(buildTree2(input, height + 1, maxHeight));
        }
        if (!input.isEmpty()) {
            tree.setValue(input.poll());
        }
        if (height < maxHeight) {
            tree.setRightChild(buildTree2(input, height + 1, maxHeight));
        }
        return tree;
    }

    /**
     * 后序建樹(shù)
     *
     * @return
     */
    public static Tree buildTree3(Queue<Integer> input, int height, int maxHeight) {
        // TODO: 2022/1/12 根節(jié)點(diǎn)就是當(dāng)前index這個(gè)節(jié)點(diǎn)
        Tree tree = new Tree();

        if (height < maxHeight) {
            tree.setLeftChild(buildTree3(input, height + 1, maxHeight));
        }

        if (height < maxHeight) {
            tree.setRightChild(buildTree3(input, height + 1, maxHeight));
        }
        if (!input.isEmpty()) {
            tree.setValue(input.poll());
        }
        return tree;
    }

    public static void print1(Tree tree) {
        if (Objects.isNull(tree)) return;
        if (Objects.nonNull(tree.getValue())) {
            System.out.print(tree.getValue());
        }
        if (Objects.nonNull(tree.getLeftChild())) {
            print1(tree.getLeftChild());
        }
        if (Objects.nonNull(tree.getRightChild())) {
            print1(tree.getRightChild());
        }
    }

    public static void print2(Tree tree) {
        if (Objects.isNull(tree)) return;
        if (Objects.nonNull(tree.getLeftChild())) {
            print2(tree.getLeftChild());
        }
        if (Objects.nonNull(tree.getValue())) {
            System.out.print(tree.getValue());
        }
        if (Objects.nonNull(tree.getRightChild())) {
            print2(tree.getRightChild());
        }
    }

    public static void print3(Tree tree) {
        if (Objects.isNull(tree)) return;
        if (Objects.nonNull(tree.getLeftChild())) {
            print3(tree.getLeftChild());
        }
        if (Objects.nonNull(tree.getRightChild())) {
            print3(tree.getRightChild());
        }
        if (Objects.nonNull(tree.getValue())) {
            System.out.print(tree.getValue());
        }
    }

    public static void demoPrint() {
        int[] a = new int[]{1, 2, 3, 4, 5, 6, 7};
        Tree tree = buildTreePrologue(a, 0);
        print1(tree);
        System.out.println();
        print2(tree);
        System.out.println();
        print3(tree);
    }

    public static void main(String[] args) {
        demoPrint();
    }
}

最終的結(jié)果如下:

以上就是詳解Java 二叉樹(shù)的實(shí)現(xiàn)和遍歷的詳細(xì)內(nèi)容,更多關(guān)于Java二叉樹(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot實(shí)現(xiàn)發(fā)送郵件

    Spring Boot實(shí)現(xiàn)發(fā)送郵件

    這篇文章主要為大家詳細(xì)介紹了Spring Boot實(shí)現(xiàn)發(fā)送郵件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • java如何根據(jù)PostMan發(fā)送請(qǐng)求設(shè)置接口請(qǐng)求工具類

    java如何根據(jù)PostMan發(fā)送請(qǐng)求設(shè)置接口請(qǐng)求工具類

    在Java中調(diào)用第三方接口可以通過(guò)不同的方式,如使用GET、POST等請(qǐng)求,關(guān)鍵點(diǎn)包括設(shè)置正確的請(qǐng)求方式、URL、參數(shù)(params)、頭信息(headers)和請(qǐng)求體(body),對(duì)于不同的數(shù)據(jù)格式,如XML和JSON,需在header中聲明內(nèi)容類型
    2024-09-09
  • Idea配置maven-tomcat-plugin插件實(shí)現(xiàn)項(xiàng)目部署

    Idea配置maven-tomcat-plugin插件實(shí)現(xiàn)項(xiàng)目部署

    今天小編就為大家分享一篇關(guān)于Idea配置maven-tomcat-plugin插件實(shí)現(xiàn)項(xiàng)目部署,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-02-02
  • 解決idea打包成功但是resource下的文件沒(méi)有成功的問(wèn)題

    解決idea打包成功但是resource下的文件沒(méi)有成功的問(wèn)題

    這篇文章主要介紹了解決idea打包成功但是resource下的文件沒(méi)有成功的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • 數(shù)據(jù)同步利器DataX簡(jiǎn)介及如何使用

    數(shù)據(jù)同步利器DataX簡(jiǎn)介及如何使用

    DataX?是阿里云?DataWorks數(shù)據(jù)集成?的開(kāi)源版本,使用Java?語(yǔ)言編寫,在阿里巴巴集團(tuán)內(nèi)被廣泛使用的離線數(shù)據(jù)同步工具/平臺(tái),今天給大家分享一個(gè)阿里開(kāi)源的數(shù)據(jù)同步工具DataX,在Github擁有14.8k的star,非常受歡迎
    2024-02-02
  • centos 安裝java環(huán)境的多種方法

    centos 安裝java環(huán)境的多種方法

    本文給大家分享三種方法幫助大家安裝jdk,有利用yum來(lái)安裝jdk還有通過(guò)手動(dòng)解壓jdk的操作方法,每種方法給大家介紹的都非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(圖文)

    Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(圖文)

    這篇文章主要介紹了Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • Java實(shí)現(xiàn)的程序員老黃歷實(shí)例

    Java實(shí)現(xiàn)的程序員老黃歷實(shí)例

    這篇文章主要介紹了Java實(shí)現(xiàn)的程序員老黃歷實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端主動(dòng)推送消息方式

    SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端主動(dòng)推送消息方式

    這篇文章主要介紹了SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端主動(dòng)推送消息方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 淺談Java中方法參數(shù)傳遞的問(wèn)題

    淺談Java中方法參數(shù)傳遞的問(wèn)題

    下面小編就為大家?guī)?lái)一篇淺談Java中方法參數(shù)傳遞的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08

最新評(píng)論

福安市| 读书| 桐城市| 临邑县| 托克逊县| 乌兰察布市| 刚察县| 杭锦旗| 日照市| 黄龙县| 五寨县| 繁昌县| 曲阜市| 尼玛县| 安宁市| 蒙阴县| 德兴市| 黄浦区| 宁津县| 平原县| 潍坊市| 马边| 长寿区| 高州市| 怀宁县| 鄂尔多斯市| 潢川县| 天津市| 马关县| 宁德市| 博客| 夏邑县| 侯马市| 宜良县| 宿迁市| 马公市| 柘荣县| 玉溪市| 石台县| 乐山市| 厦门市|