1、基本概念
二叉樹 是一種簡單的樹形結構,是每個節點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹是一種遞歸結構。
二叉樹的基本概念
- 空樹:不包含任何節點的二叉樹成爲空樹。只包含一個節點的二叉樹稱爲一個單點樹。
- 父節點和子節點:一顆二叉樹的根節點稱爲該數的子樹根節點的父節點,與之對應的,子數的根節點稱爲二叉樹樹根節點的子節點。注意父節點和子節點是相對的。
- 葉子節點:在二叉樹中沒有子節點的節點稱爲葉子節點。
- 分支節點:只有存在子節點的節點都是分之節點。
- 度數:一個節點的子節點的個數稱爲該節點的度數。即 葉子節點的度數永遠爲0,分之節點的度數爲1或2。
- 二叉樹的層:二叉樹是一種層次結構,根節點稱爲二叉樹的0層,從根節點到任一節點的路徑長度就是該節點所在的層數,也稱爲該節點的層數。
- 二叉樹的高度:也稱爲深度,就是樹中節點的最大層數。
二叉樹的性質
- 性質1: 在二叉樹的第i層上至多有2^(i-1)個結點(i>0)
- 性質2: 高度爲h的二叉樹至多有2^h - 1個結點(h>0)
- 性質3: 對於任意一棵二叉樹,如果其葉結點數爲N0,而度數爲2的結點總數爲N2,則N0=N2+1;
- 性質4:具有n個結點的完全二叉樹的深度必爲 log2(n+1)
- 性質5:對完全二叉樹,若從上至下、從左至右編號,則編號爲i 的結點,其左孩子編號必爲2i,其右孩子編號必爲2i+1;其雙親的編號必爲i/2(i=1 時爲根,除外)
滿二叉樹:如果二叉樹中所有分支節點的度數都是2,這樣的二叉樹稱爲滿二叉樹。
完全二叉樹:若設二叉樹的高度爲h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第h層有葉子結點,並且葉子結點都是從左到右依次排布,這就是完全二叉樹。
二叉樹的遍歷:
深度優先遍歷:
深度優先搜索(Depth First Search)是沿着樹的深度遍歷樹的節點,儘可能深的搜索樹的分支。
那麼深度遍歷有重要的三種方法。這三種方式常被用於訪問樹的節點,它們之間的不同在於訪問每個節點的次序不同。
這三種遍歷分別叫做先序遍歷(preorder),中序遍歷(inorder)和後序遍歷(postorder)。
先序遍歷:在先序遍歷中,先訪問根節點,然後遞歸使用先序遍歷訪問左子樹,再遞歸使用先序遍歷訪問右子樹。即 根節點->左子樹->右子樹
中序遍歷:在中序遍歷中,遞歸使用中序遍歷訪問左子樹,然後訪問根節點,最後再遞歸使用中序遍歷訪問右子樹。即 左子樹->根節點->右子樹
後序遍歷:在後序遍歷中,先遞歸使用後序遍歷訪問左子樹和右子樹,最後訪問根節點。即 左子樹->右子樹->根節點
廣度優先遍歷:
是按路徑長度由近到遠地訪問節點。也就是按二叉樹的層次逐層訪問樹中各個節點,這種遍歷不能寫成一個遞歸過程。
2、二叉樹基於Python 列表的簡單實現
# 二叉樹基於Python語言list的實現
class BinTreeListWay(object):
"""
二叉樹類
"""
def __init__(self, data, left=None, right=None):
self.__bintree = [data,left, right]
def is_empty(self):
"""
判斷二叉樹是否爲空
"""
return self.__bintree == None
def root(self):
"""
返回根節點
"""
return self.__bintree[0]
def left(self):
return self.__bintree[1]
def right(self):
return self.__bintree[2]
def set_root(self, data):
"""
設置根節點
"""
self.__bintree[0] = data
def set_left(self, data):
self.__bintree[1] =data
def set_right(self, data):
self.__bintree[2] = data
def show(self):
"""
返回二叉樹
"""
return self.__bintree
if __name__ == "__main__":
d_tree = BinTreeListWay('D', 'F', 'G')
e_tree = BinTreeListWay('E', 'I', 'H')
c_tree = BinTreeListWay('C', d_tree.show(), e_tree.show())
a_tree = BinTreeListWay('A', 'B')
a_tree.set_right(c_tree.show())
print(a_tree.show())
3、二叉樹基於Python自建類的實現
# 二叉樹基於Python語言面自建類的實現
class Node(object):
"""
節點類
"""
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
class BinTreeClassWay(object):
"""
二叉樹類
"""
def __init__(self, root=None):
self.root = root
def is_empty(self):
"""
判斷二叉樹是否爲空
"""
return self.root == None
def add(self, data):
"""
添加節點,此方法無法控制將節點掛在到那顆子樹,也就意味着它最終形成的二叉樹爲完全二叉樹或滿二叉樹
"""
# 實例化一個新的節點對象
node = Node(data)
# 如果樹是空的,則對根節點數據元素賦值
if self.root == None:
self.root = node
else:
# 創建一個存放節點的隊列
queue = []
queue.append(self.root)
# 對已有的節點按層次進行遍歷
while queue:
# 彈出隊列的第一個節點
head = queue.pop(0)
if head.left == None:
head.left = node
return
elif head.right == None:
head.right = node
return
else:
#如果左右子樹都不爲空,加入隊列繼續判斷
queue.append(head.left)
queue.append(head.right)
# 基於深度優先遍歷
def preorder(self, bin_tree):
"""
先序遍歷方法: 根節點->左子樹->右子樹
"""
if bin_tree == None:
return
print(bin_tree.data)
self.preorder(bin_tree.left)
self.preorder(bin_tree.right)
# 基於深度優先遍歷
def inorder(self, bin_tree):
"""
中序遍歷方法: 左子樹->根節點->右子樹
"""
if bin_tree == None:
return
self.preorder(bin_tree.left)
print(bin_tree.data)
self.preorder(bin_tree.right)
# 基於深度優先遍歷
def postorder(self, bin_tree):
"""
後序遍歷方法: 左子樹->右子樹->根節點
"""
if bin_tree == None:
return
self.preorder(bin_tree.left)
self.preorder(bin_tree.right)
print(bin_tree.data)
# 基於廣度優先遍歷
def breadth_first_travel(self, bin_tree):
"""
廣度優先遍歷
"""
if bin_tree == None:
return
# 該方法和 add 方法中的插入元素類似
queue = []
queue.append(bin_tree)
while queue:
node = queue.pop(0)
print(node.data)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
def show(self):
"""
返回二叉樹
"""
return self.root
if __name__ == "__main__":
bin_tree = BinTreeClassWay()
bin_tree.add('A')
bin_tree.add('B')
bin_tree.add('C')
bin_tree.add('D')
bin_tree.add('E')
bin_tree.add('F')
bin_tree.add('G')
print('先序遍歷')
bin_tree.preorder(bin_tree.show())
print('中序遍歷')
bin_tree.inorder(bin_tree.show())
print('後序遍歷')
bin_tree.postorder(bin_tree.show())
print('廣度優先遍歷')
bin_tree.breadth_first_travel(bin_tree.show())