Python數據結構與算法—樹形結構、二叉樹

基礎概念

1.定義:樹(Tree)是n(n≥0)個節點的有限集合T,它知足兩個條件:有且僅有一個特定的稱爲根(Root)的節點;其他的節點能夠分爲m(m≥0)個互不相交的有限集合T一、T二、……、Tm,其中每個集合又是一棵樹,並稱爲其根的子樹(Subtree)。node

2.基本概念ide

  • 一個節點的子樹的個數稱爲該節點的度數,一棵樹的度數是指該樹中節點的最大度數。
  • 度數爲零的節點稱爲樹葉或終端節點,度數不爲零的節點稱爲分支節點,除根節點外的分支節點稱爲內部節點。
  • 一個節點的子樹之根節點稱爲該節點的子節點,該節點稱爲它們的父節點,同一節點的各個子節點之間稱爲兄弟節點。一棵樹的根節點沒有父節點,葉節點沒有子節點。
  • 一個節點系列k1,k2, ……,ki,ki+1, ……,kj,並知足ki是ki+1的父節點,就稱爲一條從k1到kj的路徑,路徑的長度爲j-1,即路徑中的邊數。路徑中前面的節點是後面節點的祖先,後面節點是前面節點的子孫。
  • 節點的層數等於父節點的層數加一,根節點的層數定義爲一。樹中節點層數的最大值稱爲該樹的高度或深度。
  • m(m≥0)棵互不相交的樹的集合稱爲森林。樹去掉根節點就成爲森林,森林加上一個新的根節點就成爲樹。

二叉樹

定義與特徵

1.定義:二叉樹(Binary Tree)是n(n≥0)個節點的有限集合,它或者是空集(n=0),或者是由一個根節點以及兩棵互不相交的、分別稱爲左子樹和右子樹的二叉樹組成。二叉樹與普通有序樹不一樣,二叉樹嚴格區分左孩子和右孩子,即便只有一個子節點也要區分左右。函數

2.二叉樹的特徵post

  • 二叉樹第i(i≥1)層上的節點最多爲2^{i-1}2i1個。
  • 深度爲k(k≥1)的二叉樹最多有2^k-12k1個節點。
  • 在任意一棵二叉樹中,樹葉的數目比度數爲2的節點的數目多一。
  • 滿二叉樹 :深度爲k(k≥1)時有2^k-12k1個節點的二叉樹。
  • 徹底二叉樹 :只有最下面兩層有度數小於2的節點,且最下面一層的葉節點集中在最左邊的若干位置上。

二叉樹的遍歷

遍歷 :沿某條搜索路徑周遊二叉樹,對樹中的每個節點訪問一次且僅訪問一次。spa

先序遍歷: 先訪問樹根,再訪問左子樹,最後訪問右子樹;
中序遍歷: 先訪問左子樹,再訪問樹根,最後訪問右子樹;
後序遍歷: 先訪問左子樹,再訪問右子樹,最後訪問樹根;
層次遍歷: 從根節點開始,逐層從左向右進行遍歷。設計

遞歸思想和實踐

1.什麼是遞歸?code

所謂遞歸函數是指一個函數的函數體中直接調用或間接調用了該函數自身的函數。這裏的直接調用是指一個函數的函數體中含有調用自身的語句,間接調用是指一個函數在函數體裏有調用了其它函數,而其它函數又反過來調用了該函數的狀況。對象

2.遞歸函數調用的執行過程分爲兩個階段blog

遞推階段:從原問題出發,按遞歸公式遞推從未知到已知,最終達到遞歸終止條件。
迴歸階段:按遞歸終止條件求出結果,逆向逐步代入遞歸公式,迴歸到原問題求解。遞歸

3.優勢與缺點

優勢:遞歸能夠把問題簡單化,讓思路更爲清晰,代碼更簡潔
缺點:遞歸因系統環境影響大,當遞歸深度太大時,可能會獲得不可預知的結果

# 求n的階乘
def recursion(n): # 遞歸終止條件
  if n < 1: return 1
  return n * recursion(n - 1) print("n!=",recursion(5))

二叉樹的代碼實現

二叉樹順序存儲

二叉樹自己是一種遞歸結構,能夠使用Python list 進行存儲。可是若是二叉樹的結構比較稀疏的話浪費的空間是比較多的。

  • 空結點用None表示
  • 非空二叉樹用包含三個元素的列表[d,l,r]表示,其中d表示根結點,l,r左子樹和右子樹。
 1 ['A',['B',None,None  2  ],  3      ['C',['D',['F',None,None],  4                ['G',None,None],  5  ],  6           ['E',['H',None,None],  7                ['I',None,None],  8  ],  9  ] 10 ]
順序存儲代碼
 1 bitree.py 二叉樹的實現  2 
 3 思路分析:   4 1. 使用鏈式存儲  5   節點類設計上有兩個屬性變量引用左孩子和右孩子  6 2. 操做類完成二叉樹的遍歷  7 """
 8 from day2.squeue import SQueue  9 
10 # 二叉樹節點 11 class TreeNode: 12  def __init__(self, data=None, left=None, right=None): 13  self.data = data 14  self.left = left 15  self.right = right 16 
17 #  二叉樹操做 18 class Bitree: 19  def __init__(self, root=None): 20  self.root = root # 獲取樹根 21 
22  # 先序遍歷 23  def preOrder(self,node): 24  if node is None: 25  return 26  print(node.data,end=' ') 27  self.preOrder(node.left) 28  self.preOrder(node.right) 29 
30  #  中序遍歷 31  def inOrder(self, node): 32  if node is None: 33  return 34  self.inOrder(node.left) 35  print(node.data, end=' ') 36  self.inOrder(node.right) 37 
38  #  後序遍歷 39  def postOrder(self, node): 40  if node is None: 41  return 42  self.postOrder(node.left) 43  self.postOrder(node.right) 44  print(node.data, end=' ') 45 
46  # 層次遍歷 47  def levelOrder(self,node): 48  sq = SQueue() 49  sq.enqueue(node) # 從node遍歷 50  while not sq.is_empty(): 51  node = sq.dequeue() # 出隊一個 52  print(node.data,end=' ') # 遍歷數據 53  if node.left: 54  sq.enqueue(node.left) 55  if node.right: 56  sq.enqueue(node.right) 57 
58 if __name__ == "__main__": 59  #  後序遍歷 BFGDIHECA 60  # 構建樹 (筆記中) 61  b = TreeNode('B') 62  f = TreeNode('F') 63  g = TreeNode('G') 64  d = TreeNode('D', f, g) 65  i = TreeNode('I') 66  h = TreeNode('H') 67  e = TreeNode('E', i, h) 68  c = TreeNode('C', d, e) 69  a = TreeNode('A', b, c) # 樹根 70 
71  #  初始化樹對象,獲得樹根 72  bt = Bitree(a) 73  # 先序 74  bt.preOrder(bt.root) 75  print() 76  #  中序 77  bt.inOrder(bt.root) 78  print() 79  bt.postOrder(bt.root) 80  print() 81  bt.levelOrder(bt.root) 82  print()
鏈式存儲代碼
相關文章
相關標籤/搜索