1.二叉樹定義特點:
定義:二叉樹是n(n>=0)個結點的有限集合,該集合或者為空集(稱為空二叉樹),或者由一個根結點和兩棵互不相交的、分別稱為根結點的左子樹和右子樹的二叉樹組成。它是樹中的一種。
特點:
1)樹中每個節點最多只能有兩棵樹,即每個節點的度最多為2。(ps;度也就是葉子的概念)
2)二叉樹的子樹有左右之分,即左子樹與右子樹,次序不能顛倒。
3)二叉樹即使只有一個子樹時,也要區分是左子樹還是右子樹。
這里說一下特殊的幾種二叉樹:斜樹(左斜樹與右斜樹)、滿二叉樹、完全二叉樹。具體百度或者看(大話數據結構)。完全二叉樹可以理解為滿二叉樹少一點點。這兩種樹的深度比較容易計算。
1.1 滿二叉樹
滿二叉樹作為一種特殊的二叉樹,它是指:所有的分支節點都存在左子樹與右子樹,並且所有的葉子節點都在同一層上。其特點有:
(1)葉子節點只能出現在最下面一層
(2)非葉子節點度一定是2
(3)在同樣深度的二叉樹中,滿二叉樹的節點個數最多,節點個數為: 2h−1 ,其中 h 為樹的深度。

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

2.二叉樹的建立
3.二叉樹的五種遍歷
常見的五種遍歷:前序遍歷、中序遍歷、后序遍歷,層次遍歷,深度優先遍歷,看這里。
以下遍歷以該二叉樹為例:

3.1 前序遍歷
思想:先訪問根節點,再先序遍歷左子樹,然后再先序遍歷右子樹。總的來說是根—左—右
上圖先序遍歷結果為為:1,2,4,8,9,5,3,6,7
代碼如下:
def PreOrder(self, root):
'''打印二叉樹(先序)'''
if root == None:
return
print(root.val, end=' ')
self.PreOrder(root.left)
self.PreOrder(root.right)
3.2 中序遍歷
思想:先中序訪問左子樹,然后訪問根,最后中序訪問右子樹。總的來說是左—根—右
上圖中序遍歷結果為為:8,4,9,2,5,1,6,3,7
代碼如下:
def InOrder(self, root):
'''中序打印'''
if root == None:
return
self.InOrder(root.left)
print(root.val, end=' ')
self.InOrder(root.right)
3.3 后序遍歷
思想:先后序訪問左子樹,然后后序訪問右子樹,最后訪問根。總的來說是左—右—根
上圖后序遍歷結果為為:8,9,4,5,2,6,7,3,1
代碼如下:
def BacOrder(self, root):
'''后序打印'''
if root == None:
return
self.BacOrder(root.left)
self.BacOrder(root.right)
print(root.val, end=' ')
3.4 層次遍歷(寬度優先遍歷)
思想:利用隊列,依次將根,左子樹,右子樹存入隊列,按照隊列的先進先出規則來實現層次遍歷。
上圖后序遍歷結果為為:1,2,3,4,5,6,7,8,9
代碼如下:
def BFS(self, root):
'''廣度優先'''
if root == None:
return
# queue隊列,保存節點
queue = []
# res保存節點值,作為結果
#vals = []
queue.append(root)
while queue:
# 拿出隊首節點
currentNode = queue.pop(0)
#vals.append(currentNode.val)
print(currentNode.val, end=' ')
if currentNode.left:
queue.append(currentNode.left)
if currentNode.right:
queue.append(currentNode.right)
#return vals
3.5 深度優先遍歷
思想:利用棧,先將根入棧,再將根出棧,並將根的右子樹,左子樹存入棧,按照棧的先進后出規則來實現深度優先遍歷。
上圖后序遍歷結果為為:1,2,4,8,9,5,3,6,7
代碼如下:
def DFS(self, root):
'''深度優先'''
if root == None:
return
# 棧用來保存未訪問節點
stack = []
# vals保存節點值,作為結果
#vals = []
stack.append(root)
while stack:
# 拿出棧頂節點
currentNode = stack.pop()
#vals.append(currentNode.val)
print(currentNode.val, end=' ')
if currentNode.right:
stack.append(currentNode.right)
if currentNode.left:
stack.append(currentNode.left)
#return vals
3.6 代碼運行結果

4.二叉樹一道劍指上的例題:
解題與調試全代碼:
#!/usr/bin/env python #-*-coding:utf-8 -*- class Node(object): def __init__(self, number): self.val = number self.left = None self.right = None class Tree(object): lis = [] def __init__(self): self.root = None def add(self, number): node = Node(number) if self.root == None: self.root = node Tree.lis.append(self.root) else: while True: point = Tree.lis[0] if point.left == None: point.left = node Tree.lis.append(point.left) return elif point.right == None: point.right = node Tree.lis.append(point.right) Tree.lis.pop(0) return #先序遍歷函數 def preOrderTrave(self, bt): if bt is not None: print(bt.val, end=" ") self.preOrderTrave(bt.left) self.preOrderTrave(bt.right) def FindPath(root, expectNumber): # write code here if not root: return [] if root and not root.left and not root.right and root.val == expectNumber: return [[root.val]] res = [] print(root.val,expectNumber) left = FindPath(root.left, expectNumber-root.val) right = FindPath(root.right, expectNumber-root.val) for i in left+right: res.append([root.val]+i) return res if __name__ == '__main__': t = Tree() data_list = [10,5,12,4,7] for x in data_list: t.add(x) t.preOrderTrave(t.root) # 以上是創建書中的二叉樹,下面是解題 res = FindPath(t.root, 22) print(res)