數據結構 - 二叉樹簡介

在《大話數據結構》一中有這樣一段話“無論多高大的樹,那也是從小到大的,由根到葉,一點點成長起來的,俗話說十年樹木,百年樹人,可一棵大樹又何止十年這樣容易”。所以了解二叉樹的算法,必先了解樹的基本概念。

1.樹的基本概念

① 節點、根節點、父節點、子節點、兄弟節點
② 一棵樹可以沒有任何節點,成為空樹
③ 一棵樹可以只有1個節點,也就是只有根節點
④ 子樹、左子樹、右子樹
⑤ 節點的(degree):子樹的個數
⑥ 樹的:所有節點度中的最大值
⑦ 葉子節點(leaf): 度為0的節點
⑧ 非葉子節點:度不為0的節點

001.png

2.樹的深度

① 層數(level):根節點在第1層,根節點的子節點在第2層。
② 節點的深度(depth): 從根節點到當前節點的唯一路徑上的及節點總數。
③ 節點的高度(height):從當前節點到最遠葉子節點的路徑上的節點總數。
④ 樹的深度:所有節點深度中的最大值。
⑤ 樹的高度:左右節點高中中的最大值
⑥ 樹的深度等于樹的高度。

002.png

3.二叉樹(Binary Tree)

二叉樹的特點
1.每個節點的度最大為2(最多擁有2棵子樹)
2.左子樹和右子樹是有順序的
3.即使某節點只有一顆子樹,也要區分左右子樹。

二叉樹具有五種基本形態:
1.空二叉樹。
2.只有一個根節點
3.根節點只有左子樹
4.根節點只有右子樹
5.根節點既有左子樹又有右子樹。

所以,二叉樹是有序樹

003.png

3-1.二叉搜索(Binary Search Tree)

二叉搜索樹是二叉樹的一種,是應用非常廣泛的一種二叉樹,又被成為:兒茶查找樹,二叉排序樹。

二叉搜索樹的特點:
1.任意一個節點的值都大于其左子樹所有節點的值。
2.任意一個節點的值都小于其右子樹所有節點的值。
3.它的左右子樹也是一棵二叉搜索樹。

二叉搜索樹的作用:
二叉搜索書可以大大提高搜索數據的效率
二叉搜索存儲的元素必須具備可比較性
(1). 比如Int、double等
(2). 如果是自定義類型,需要制定比較方式
(3). 不允許為null

004.png

3-2.真二叉樹(Proper Binary Tree)

真二叉樹:所有節點的度要么為0,要么為2。

005.png

3-3. 滿二叉樹(Full Binary Tree)

滿二叉樹:最后一層節點的度都為0,其他節點的度都為2.
在同樣高度的二叉樹中,滿二叉樹的葉子節點數量最多,總結點數量最多。
滿二叉樹一定是真二叉樹,真二叉樹樹不一定是滿二叉樹。

006.png

3-4.完全叉樹(Complete Binary Tree)

對完全二叉樹:對節點從上至下、左至右開始編號,其所有編號都能與相同高度的滿二叉樹種的編號對應。

葉子節點指揮出現在最后2層,最后1層的葉子節點都靠左對齊。

完全二叉樹從根節點至倒數第2層是一顆滿二叉樹。
滿二叉樹一定是完全二叉樹,完全二叉樹不一定是滿二叉樹

007.png

4.二叉樹的遍歷

二叉樹的產檢遍歷有4中方法:

● 前序遍歷(Preorder Traversal)

● 中序遍歷(Inorder Traversal)

● 后序遍歷(Postorder Traversal)

● 層序遍歷(Level Order Traversal)

4-1.前序遍歷(Preorder Traversal)

訪問順序
根節點、前序遍歷左子樹、前序遍歷右子樹
7, 4 ,2 , 1, 3 , 5 , 9, 8 , 11 , 10 ,12

前序遍歷.png

前序遍歷核心代碼:(遞歸思想)

    /**
     * 前序遍歷
     */
    public void preorderTraversal() {
        preorderTraversal(root);
    }
    
    private void preorderTraversal(Node<E> node) {
        if (node == null) return;
        
          System.out.println(node.element);
        preorderTraversal(node.left);
        preorderTraversal(node.right);
    }

4-2 中序遍歷(Inorder Traversal)

訪問順序
中序遍歷左子樹根節點,中序遍歷右子樹
1, 2 ,3 , 4, 5 , 7 , 8, 9 , 10 , 11 ,12

中序遍歷.png

中序遍歷核心代碼:(遞歸思想)

    /**
     * 中序遍歷
     */
    public void inorderTraversal() {
        inorderTraversal(root);
    }
    
    private void inorderTraversal(Node<E> node) {
        if (node == null) return;
        
        inorderTraversal(node.left);
         System.out.println(node.element);
        inorderTraversal(node.right);
    }

4-3 后序遍歷(Postorder Traversal)

訪問順序
后序遍歷左子樹、后序遍歷右子樹根節點
1, 3 ,2 , 5, 4 , 8 , 10 , 12 ,11, 9 , 7

后序遍歷.png

后序遍歷核心代碼:(遞歸思想)

    /**
     * 后序遍歷
     */
    public void postorderTraversal() {
        postorderTraversal(root);
    }
    
    private void postorderTraversal(Node<E> node) {
        if (node == null) return;

        postorderTraversal(node.left);
        postorderTraversal(node.right);
         System.out.println(node.element);
    }

4-4 層序遍歷(Level Order Traversal)

訪問順序
從上到下從左到右依次訪問每一個節點
7, 4 ,9 , 2, 5 , 8, 11 , 1 , 3 ,10 , 12

層序遍歷.png

層序遍歷核心代碼:(隊列思想)

? 實現思路

  1. 將根節點入隊
  2. 循環執行以下操作,直到隊列為空
    ?將隊頭節點 A 出隊,進行訪問
    ?將 A 的左子節點入隊
    ?將 A 的右子節點入隊
    /**
     * 層序遍歷
     */
    public void levelOrderTraversal() {
        if (root == null) return;
        // 創建隊列
        Queue<Node<E>> queue = new LinkedList<>();
        // 將根節點入隊
        queue.offer(root);

        while (!queue.isEmpty()) {
            // 頭節點出隊
            Node<E> node = queue.poll();
            
            if (node.left != null) {
                //左節點入隊
                queue.offer(node.left);
            }
            
            if (node.right != null) {
                //右節點入隊
                queue.offer(node.right);
            }
        }
    }

以上是關于二叉樹基本概念的學習,記錄一下,方便自己日后查閱。

其它相關:
二叉搜索樹(Binary Search Tree).
AVL樹(艾薇兒樹).

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容