數據結構與算法(二叉樹結構)


一、二叉樹

  1.1 二叉樹的定義:

  二叉樹是一種特殊的樹,它具有以下特點
  (1)樹中每個節點最多只能有兩棵樹,即每個節點的度最多為2。
  (2)二叉樹的子樹有左右之分,即左子樹右子樹,次序不能顛倒。
  (3)二叉樹即使只有一個子樹時,也要區分是左子樹還是右子樹。

  1.2 滿二叉樹:

  滿二叉樹作為一種特殊的二叉樹,它是指:所有的分支節點都存在左子樹與右子樹,並且所有的葉子節點都在同一層上。其特點有:
  (1)葉子節點只能出現在最下面一層
  (2)非葉子節點度一定是2
  (3)在同樣深度的二叉樹中,滿二叉樹的節點個數最多,節點個數為: 2h12h−1 ,其中 hh 為樹的深度。

   

  1.3 完全二叉樹:

  若設二叉樹的深度為 hh ,除第 hh 層外,其它各層 (1h1)(1~h−1) 的結點數都達到最大個數,第 hh 層所有的結點都連續集中在最左邊,這就是完全二叉樹。其具有以下特點
  (1)葉子節點可以出現在最后一層或倒數第二層。
  (2)最后一層的葉子節點一定集中在左部連續位置。
  (3)完全二叉樹嚴格按層序編號。(可利用數組或列表進行實現,滿二叉樹同)
  (4)若一個節點為葉子節點,那么編號比其大的節點均為葉子節點。

  

二、二叉樹的相關性質

  2.1 二叉樹性質:

  (1)在非空二叉樹的 ii 層上,至多有 2i12i−1 個節點 (i1)(i≥1) 。
  (2)在深度為 hh 的二叉樹上最多有 2h12h−1 個節點 k1)(k≥1) 。
  (3)對於任何一棵非空的二叉樹,如果葉節點個數為 n0n0 ,度數為 22 的節點個數為 n2n2 ,則有: n0=n2+1n0=n2+1 。

  2.2 完全二叉樹性質:

  (1)具有 nn 個的結點的完全二叉樹的深度為 log2n+1log2⁡n+1 。.
  (2)如果有一顆有 nn 個節點的完全二叉樹的節點按層次序編號,對任一層的節點 i1ini,(1≥i≥n) 有:
    (2.1)如果 i=1i=1 ,則節點是二叉樹的根,無雙親,如果 i>1i>1 ,則其雙親節點為 i/2⌊i/2⌋ 。
    (2.2)如果 2i>n2i>n 那么節點i沒有左孩子,否則其左孩子為 2i2i 。
    (2.3)如果 2i+1>n2i+1>n 那么節點沒有右孩子,否則右孩子為 2i+12i+1 。

三、二叉樹的數據結構(排序方式)

想要遍歷一棵二叉樹,有兩種不同的策略:深度優先遍歷寬度(廣度)優先遍歷

其中深度優先遍歷策略有三種不同的方式:

前序遍歷:按根節點、左子樹、右子樹的順序遍歷。

中序遍歷:按左子樹、根節點、右子樹的順序遍歷。

后序遍歷:按左子樹、右子樹、根節點的順序遍歷。

四、python實現二叉樹

# 創建二叉樹節點
class Node(object):
    def __init__(self,item):
        self.item = item
        self.left = None
        self.right = None
        
        
# 創建二叉樹
class Tree(object):
    # 構建一顆空二叉樹
    def __init__(self):
        # 指針指向根節點,當前樹為空,指向None
        self.root = None
        
    # 添加子節點
    def addNode(self,item):
        node = Node(item)
        cur = self.root
        
        # 判斷如果新節點是根節點
        if self.root == None:
            self.root = node
            return
            
        # 如果樹不為空情況,需要通過隊列循環來遍歷節點是否為空
        # 先將根節點指針放入列表,作為遍歷起始點
        q = [cur]
        
        while q:
            # 刪除隊列中最左側元素
            n = q.pop(0)
        
            # 判斷左節點是否為空
            if n.left == None:
                n.left = node
                break
            else:
                q.append(n.left)
                
            # 判斷右節點是否為空
            if n.right == None:
                n.right = node
                break
            else:
                q.append(n.right)
                
    # 樹的廣度遍歷
    def travel(self):
        cur = self.root
        q = [cur]
        
        while q:
            # 刪除列表中最左側(最先進入的子節點)元素
            n = q.pop(0)
            print(n.item)
            
            # 當前節點的左子節點不為None,說明子節點存在,追加子節點地址到列表
            if n.left != None:
                q.append(n.left)
            # 當前節點的右子節點不為None,說明子節點存在,追加子節點地址到列表
            if n.right != None:
                q.append(n.right)
                
                
    # 樹的深度遍歷(前序遍歷,中序遍歷,后序遍歷)
    # 前序遍歷(根左右)
    def frontTravel(self,root):
        # 判斷當子節點為空時,結束遞歸
        if root == None:
            return
        
        # 獲取節點的值
        print(root.item)
        # 通過遞歸獲取根左節點地址
        self.frontTravel(root.left)
        # 通過遞歸獲取根右節點地址
        self.frontTravel(root.right)
        
        
    # 中序遍歷(左根右)
    def midTravel(self,root):
        # 判斷當子節點為空時,結束遞歸
        if root == None:
            return
        
        # 通過遞歸獲取根左節點地址
        self.midTravel(root.left)
        # 獲取節點的值
        print(root.item)
        # 通過遞歸獲取根右節點地址
        self.midTravel(root.right)
        
        
    # 后序遍歷(左右根)
    def afterTravel(self,root):
        # 判斷當子節點為空時,結束遞歸
        if root == None:
            return
        
        # 通過遞歸獲取根左節點地址
        self.afterTravel(root.left)
        # 通過遞歸獲取根右節點地址
        self.afterTravel(root.right)
        # 獲取節點的值
        print(root.item)  

  測試:

# 測試
tree = Tree()
tree.addNode(1)
tree.addNode(2)
tree.addNode(3)
tree.addNode(4)
tree.addNode(5)
tree.addNode(6)

# 廣度遍歷樹
# tree.travel()

# 深度遍歷樹
# tree.frontTravel(tree.root)  # 1 2 4 5 3 6
# tree.midTravel(tree.root)  # 4 2 5 1 6 3
tree.afterTravel(tree.root)  # 4 5 2 6 3 1

五、排序二叉樹

  插入節點的准則:首先插入根節點。當插入其他節點的時候,需要和根節點做比較,比根節點小的節點插入樹的左側,大的插入樹的右側

class Node():
    def __init__(self,item):
        self.item = item
        self.left = None
        self.right = None


class SortTree():
    def __init__(self):
        self.root = None
        
    def midTravel(self,root):
        if root == None:
            return
        #左根右
        self.midTravel(root.left)
        print(root.item)
        self.midTravel(root.right)
        
    def insertNode(self,item):
        node = Node(item)
        cur = self.root
        #樹為空
        if self.root == None:
            self.root = node
            return
        #樹為非空
        while True:
            if cur.item > node.item:
                if cur.left == None:
                    cur.left = node
                    break
                else:
                    cur = cur.left
            else:
                if cur.right == None:
                    cur.right = node
                    break
                else:
                    cur = cur.right
        

  測試:

t = SortTree()
t.insertNode(3)
t.insertNode(8)
t.insertNode(3)
t.insertNode(1)
t.insertNode(1)

t.midTravel(t.root)

#結果:>>>
1
1
3
3
8

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM