欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

什么是二叉樹

簡單理解為對于一個節(jié)點來說,最多擁有一個上級節(jié)點,同時最多具備左右兩個下級節(jié)點的數(shù)據(jù)結(jié)構(gòu)。

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

二叉樹建樹

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

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

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

0

1 2

3 4 5 6

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

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

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

1.前序遍歷的方式建樹

new Tree(根節(jié)點);
buildTree(左子樹);
buildTree(右子樹);

2.中序遍歷的方式建樹

buildTree(左子樹);
new Tree(根節(jié)點);
buildTree(右子樹);

3.后序遍歷的方式建樹

buildTree(左子樹);
buildTree(右子樹);
new Tree(根節(jié)點);

前序建樹

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

實現(xiàn)也比較簡單

package com.chaojilaji.book.tree;

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

public class Handle {

    /**
     * 前序建樹
     *
     * @param input
     * @param index
     * @return
     */
    public static Tree buildTreePrologue(int[] input, int index) {
        // TODO: 2022/1/12 根節(jié)點就是當前index這個節(jié)點
        Tree tree = new Tree();
        tree.setValue(input[index]);
        // TODO: 2022/1/12 左右兩個節(jié)點分別為 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
        }
    }
}

中序建樹

以 1,2,3,4,5,6,7序列為例,如果是中序建樹的方式,那么二叉樹的結(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 {

    /**
     * 中序建樹
     * @param input
     * @param height
     * @param maxHeight
     * @return
     */
    public static Tree buildTree2(Queue<Integer> input, int height, int maxHeight) {
        // TODO: 2022/1/12 根節(jié)點就是當前index這個節(jié)點
        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();
    }
}

相對前序建樹以擴展的方式建立二叉樹,中序建樹由于無法很好的控制索引,所以這里使用了一個隊列來存儲整個序列,同時需要算出以當前的節(jié)點數(shù),算出建立一棵二叉平衡樹,最小的深度為多少。然后按照之前給出的偽代碼,按照左根右的方式賦值和遞歸調(diào)用即可。
運行的結(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
        }
    }
}

后序建樹

有了中序遍歷,其實后序遍歷就非常簡單了,以序列1,2,3,4,5,6,7為例,建樹應(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 {

    /**
     * 后序建樹
     *
     * @return
     */
    public static Tree buildTree3(Queue<Integer> input, int height, int maxHeight) {
        // TODO: 2022/1/12 根節(jié)點就是當前index這個節(jié)點
        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();
    }


}

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

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

二叉樹的遍歷

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

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());
    }
}

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

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 {


    /**
     * 前序建樹
     *
     * @param input
     * @param index
     * @return
     */
    public static Tree buildTreePrologue(int[] input, int index) {
        // TODO: 2022/1/12 根節(jié)點就是當前index這個節(jié)點
        Tree tree = new Tree();
        tree.setValue(input[index]);
        // TODO: 2022/1/12 左右兩個節(jié)點分別為 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;
    }

    /**
     * 中序建樹
     *
     * @param input
     * @param height
     * @param maxHeight
     * @return
     */
    public static Tree buildTree2(Queue<Integer> input, int height, int maxHeight) {
        // TODO: 2022/1/12 根節(jié)點就是當前index這個節(jié)點
        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;
    }

    /**
     * 后序建樹
     *
     * @return
     */
    public static Tree buildTree3(Queue<Integer> input, int height, int maxHeight) {
        // TODO: 2022/1/12 根節(jié)點就是當前index這個節(jié)點
        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 二叉樹的實現(xiàn)和遍歷的詳細內(nèi)容,更多關(guān)于Java二叉樹的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring項目實現(xiàn)單元測試過程解析

    spring項目實現(xiàn)單元測試過程解析

    這篇文章主要介紹了spring項目實現(xiàn)單元測試過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • Java數(shù)據(jù)結(jié)構(gòu)之實現(xiàn)跳表

    Java數(shù)據(jù)結(jié)構(gòu)之實現(xiàn)跳表

    今天帶大家來學習Java數(shù)據(jù)結(jié)構(gòu)的相關(guān)知識,文中對用Java實現(xiàn)跳表作了非常詳細的圖文解說及代碼示例,對正在學習java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • SpringMVC超詳細講解視圖和視圖解析器

    SpringMVC超詳細講解視圖和視圖解析器

    這篇文章主要介紹了springMVC中的視圖與視圖解析器,springMVC視圖的種類很多,默認有轉(zhuǎn)發(fā)視圖和重定向視圖,本文就每一種視圖給大家詳細介紹,需要的朋友可以參考下
    2022-06-06
  • Java正則替換手機號代碼實例

    Java正則替換手機號代碼實例

    本文的主要內(nèi)容是Java語言中正則表達式替換手機號的第4到第7位,實現(xiàn)方法十分簡單,同時涉及了一些正則表達式的相關(guān)用法,需要的朋友可以參考下。
    2017-09-09
  • java性能優(yōu)化之代碼緩存優(yōu)化

    java性能優(yōu)化之代碼緩存優(yōu)化

    這篇文章主要介紹了java性能優(yōu)化之代碼緩存優(yōu)化,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • JAVA使用geotools讀取shape格式文件的方法

    JAVA使用geotools讀取shape格式文件的方法

    這篇文章主要介紹了JAVA使用geotools讀取shape格式文件的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2017-01-01
  • Java對象序列化操作詳解

    Java對象序列化操作詳解

    這篇文章主要介紹了Java對象序列化操作,簡單描述了Java序列化相關(guān)概念、原理并結(jié)合實例形式總結(jié)分析了常見序列化操作相關(guān)定于與使用技巧,需要的朋友可以參考下
    2018-09-09
  • springboot+thymeleaf 文件上傳功能的實現(xiàn)代碼

    springboot+thymeleaf 文件上傳功能的實現(xiàn)代碼

    這篇文章主要介紹了springboot+thymeleaf 文件上傳功能的實現(xiàn)代碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Spring 環(huán)境下實現(xiàn)策略模式的示例

    Spring 環(huán)境下實現(xiàn)策略模式的示例

    這篇文章主要介紹了Spring 環(huán)境下實現(xiàn)策略模式的示例,幫助大家更好的理解和使用spring框架,感興趣的朋友可以了解下
    2020-10-10
  • Java結(jié)構(gòu)型設(shè)計模式之裝飾模式詳解

    Java結(jié)構(gòu)型設(shè)計模式之裝飾模式詳解

    裝飾模式(Decorator Pattern)允許向一個現(xiàn)有的對象添加新的功能,同時又不改變其結(jié)構(gòu)。這種類型的設(shè)計模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有類的一個包裝。這種模式創(chuàng)建了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能
    2023-03-03

最新評論