Java數據結構與算法分析 | 樹

GitHub源碼分享

項目主頁: https://github.com/gozhuyinglong/blog-demos
本文源碼: https://github.com/gozhuyinglong/blog-demos/tree/main/java-data-structures

1. 前言

咱們前面講到了數組鏈表兩種數據結構,其各自有本身的優缺點,咱們來回顧一下。java

  • 數組(Array)

優勢:經過下標訪問速度很是快。
缺點:須要檢索具體某個值時,或者插入值時(會總體移動)效率較低node

  • 鏈表(Linked List)

優勢:在插入某個值時,效率比數組高
缺點:檢索某個值時效率仍然較低git

咱們本篇講到的樹,便能提升數據的存儲和讀取效率。github

2. 樹(Tree)

樹是一種非線性的數據結構,它包含n(n>=1)個節點,(n-1)條邊的有窮集合。把它叫作「樹」是由於它看起來像一個倒掛的樹,也就是說它是根朝上,葉子朝下的。算法

3. 樹結構的特色

  • 樹結構的每一個元素稱爲節點(node)
  • 每一個節點都有零個或多個子節點
  • 沒有父節點的節點叫作根節點(root)
  • 每個非根結點有且只有一個父結點
  • 除了根結點外,每一個子結點能夠分爲多個不相交的子樹
  • 父子節點由一條有向的邊(edgeo)相連結。

樹結構

4. 樹的經常使用術語

結合上圖瞭解樹的經常使用術語,加深對樹的理解。數組

  • 節點(node)

樹結構中的每個元素稱爲一個節點,如上圖中的ABC......M數據結構

  • 根節點(root)

沒有父節點的節點叫作根節點,如上圖中的Aapp

  • 父節點(parent)

一個節點的上級節點叫作它的父節點,一個節點最多隻能有一個父節點,如上圖中C是F的父節點ui

  • 子節點(child)

一個節點的下級節點叫作它的子節點,一個節點的子節點能夠有多個,如上圖中的IJK是E的子節點this

  • 兄弟節點(siblings)

擁有相同父節點的節點叫作兄弟節點,如上圖中的L和M是兄弟節點

  • 葉子節點(leaf)

沒有子節點的節點叫作葉子節點,如圖中的BFGLMIJK

  • 邊(dege)

父子節點間的鏈接稱爲邊,一棵樹的邊數爲(n-1)

  • 節點的權(weight)

節點上的元素值

  • 路徑(path)

從root節點找到該節點的路線,如上圖中L的路徑爲A-D-H-L。路徑的長爲該路徑上邊的條數,L路徑的長爲3(n-1)。

  • 層(layer)

距離根節點相等的路徑長度爲一層,如上圖中A爲第一層;BCDE爲第二層;FGHIJK爲第三層;LM爲第四層

  • 子樹(child tree)

以某一節點(非root)作爲根的樹稱爲子樹,如以E爲根的樹稱爲A的子樹

  • 樹的高度(height)

樹的最大層數,上圖中樹的高度爲4

  • 森林(words)

多棵子樹構成樹林

5. 代碼實現

咱們將第3章中的樹結構圖經過Java代碼進行實現。

TreeNode類爲樹的一個節點,其中:

  • element:存儲當前節點的元素數據
  • firstChild:指向當前節點的第一個子節點(如:A的firstChild爲B;D的firstChild爲G;G的firstChild爲空)
  • nextSibling:指向當前節點的下一個兄弟節點(如:B的nextSibling爲C;G的nextSibling爲H;H的nextSibling爲空)

Tree類實現了一棵樹的初始化和遍歷,listAll遍歷算法的核心是遞歸。具體內容見代碼

public class TreeDemo {

    public static void main(String[] args) {
        new Tree().initTree().listAll();

    }

    private static class Tree {

        private TreeNode root; // 樹根

        /**
         * 初始化一棵樹
         */
        private Tree initTree() {

            TreeNode a = new TreeNode("A");
            TreeNode b = new TreeNode("B");
            TreeNode c = new TreeNode("C");
            TreeNode d = new TreeNode("D");
            TreeNode e = new TreeNode("E");
            TreeNode f = new TreeNode("F");
            TreeNode g = new TreeNode("G");
            TreeNode h = new TreeNode("H");
            TreeNode i = new TreeNode("I");
            TreeNode j = new TreeNode("J");
            TreeNode k = new TreeNode("K");
            TreeNode l = new TreeNode("L");
            TreeNode m = new TreeNode("M");

            root = a;

            a.firstChild = b;

            b.nextSibling = c;

            c.nextSibling = d;
            c.firstChild = f;

            d.nextSibling = e;
            d.firstChild = g;

            e.firstChild = i;

            g.nextSibling = h;

            h.firstChild = l;

            i.nextSibling = j;

            j.nextSibling = k;

            l.nextSibling = m;

            return this;
        }


        /**
         * 遍歷一棵樹,從root開始
         */
        public void listAll() {
            listAll(root, 0);
        }

        /**
         * 遍歷一棵樹
         *
         * @param node  樹節點
         * @param depth 層級(用於輔助輸出)
         */
        public void listAll(TreeNode node, int depth) {
            StringBuilder t = new StringBuilder();
            for (int i = 0; i < depth; i++) {
                t.append("\t");
            }
            System.out.printf("%s%s\n", t.toString(), node.element);

            // 先遍歷子節點,子節點的層級須要+1
            if (node.firstChild != null) {
                listAll(node.firstChild, depth + 1);
            }

            // 後遍歷兄弟節點,兄弟節點的層級不變
            if (node.nextSibling != null) {
                listAll(node.nextSibling, depth);
            }
        }


    }

    private static class TreeNode {
        private final Object element; // 當前節點數據
        private TreeNode firstChild; // 當前節點的第一個子節點
        private TreeNode nextSibling; // 當前節點的下一個兄弟節點

        public TreeNode(Object element) {
            this.element = element;
        }

    }
}

輸出結果:

A
    B
    C
        F
    D
        G
        H
            L
            M
    E
        I
        J
        K
相關文章
相關標籤/搜索