「掃盲」數據結構 - 二叉樹入門

什麼是二叉樹

有一個根節點 向下擴展兩個子節點 兩個子節點又能夠向下擴展。相似於這樣的結構成爲二叉樹node

<img src="https://gitee.com/xiaoxiunique/picgo-image/raw/master/atips/image-20200318164309773.png" alt="image-20200318164309773" style="zoom:50%;" />python

上面這種就夠就是二叉樹,固然有二叉樹就有三叉樹、四叉樹。git

<img src="https://gitee.com/xiaoxiunique/picgo-image/raw/master/atips/image-20200318164534883.png" alt="image-20200318164534883" style="zoom:50%;" />數組

樹中相應節點的概念

<img src="https://gitee.com/xiaoxiunique/picgo-image/raw/master/atips/image-20200318165011873.png" alt="image-20200318165011873" style="zoom:50%;" />app

  • A 節點是 B 節點的【父節點
  • B 節點是 A 節點的【子節點
  • B、C、D 這三個節點的父親節點是同一個節點,因此他們之間互稱爲【兄弟節點
  • E 節點沒有父親節點,因此咱們把它稱爲【根節點
  • G、H、I、J、K、L 沒有子節點,因此咱們把它稱爲【葉子節點
  • 節點的高度:節點到葉子節點的最長路徑
  • 節點的深度:根節點到這個節點所經歷的節點個數
  • 節點的層數:節點的深度 + 1

二叉樹的種類

在二叉樹之上,具有各類各樣的其餘屬性,就會衍生出其餘的樹結構。工具

  • 滿二叉樹

    <img src="https://gitee.com/xiaoxiunique/picgo-image/raw/master/atips/image-20200318170240608.png" alt="image-20200318170240608" style="zoom:50%;" />spa

    葉子節點全都在最底層,除葉子節點外,每一個節點都有兩個子節點,這種二叉樹叫作【滿二叉樹】。指針

  • 徹底二叉樹

    <img src="https://gitee.com/xiaoxiunique/picgo-image/raw/master/atips/image-20200318170532465.png" alt="image-20200318170532465" style="zoom:50%;" />code

    葉子節點都在最底下兩層,最後一次的葉子節點都靠左排列,而且除了最後一層,其餘層的節點個數都要達到最大,這種二叉樹叫作【徹底二叉樹排序

  • 二分搜索樹

    <img src="https://gitee.com/xiaoxiunique/picgo-image/raw/master/atips/image-20200318171007366.png" alt="image-20200318171007366" style="zoom:50%;" />

    若任意節點的左子樹不爲空,則左子樹上全部節點的值均小於它的根節點的值;

    若任意節點的右子樹不爲空,則右子樹上全部節點的值均大於或等於它的根節點的值;

    任何左子樹或右子樹也都爲二分搜索樹。

  • <img src="https://gitee.com/xiaoxiunique/picgo-image/raw/master/atips/image-20200318195545250.png" alt="image-20200318195545250" style="zoom:50%;" />

    堆就是用數組實現的二叉樹,因此它沒有使用父指針或子指針。堆根據堆屬性來排序。

    堆的經常使用方法

    構建優先隊列、支持堆排序、支持找出一個集合中最小值(或者最大值)

    堆分爲兩種:最大堆和最小堆,二者的差異在於節點的排序方式。

    在最大堆中,父節點的值每個子節點的值都要大。在最小堆中,父節點的值比每個子節點的值都要小。這就是所謂的「堆屬性」,而且這個屬性對堆中的每個節點都成立。

  • AVL
  • 紅黑樹
  • 線段樹
  • 字典樹
  • 並查集

樹的遍歷

  • 前序 根左右
  • 中序 左根有
  • 後序 左右根
  • DFS 深度優先遍歷

    代碼模板(遞歸寫法)

    visited = set() 
    
    def dfs(node, visited):
        if node in visited: # terminator
            # already visited 
            return 
    
        visited.add(node) 
    
        # process current node here. 
        ...
        for next_node in node.children(): 
            if next_node not in visited: 
                dfs(next_node, visited)

    非遞歸寫法

    def DFS(self, tree): 
    
        if tree.root is None: 
            return [] 
    
        visited, stack = [], [tree.root]
    
        while stack: 
            node = stack.pop() 
            visited.add(node)
    
            process (node) 
            nodes = generate_related_nodes(node) 
            stack.push(nodes) 
    
        # other processing work 
        ...
  • BFS 廣度優先遍歷(層序遍歷)

    代碼模板

    def BFS(graph, start, end):
        visited = set()
        queue = [] 
        queue.append([start]) 
    
        while queue: 
            node = queue.pop() 
            visited.add(node)
    
            process(node) 
            nodes = generate_related_nodes(node) 
            queue.push(nodes)
    
        # other processing work 
        ...
本文由博客羣發一文多發等運營工具平臺 OpenWrite 發佈
相關文章
相關標籤/搜索