概述
- 前言
- 什麼是樹
- 什麼是二叉樹
- 深度優先
- 廣度優先
- 後記
前言
前面說到演算法被虐了,這回我要好好把它啃下來。哪裡跌倒就要從哪裡站起來。這是我複習演算法與資料結構時的小筆記,這裡就 po 出來,給大家也複習一下舊的知識點,查缺補漏。如果我的文章對你有幫助,歡迎關注、點贊、轉發,這樣我會更有動力做原創分享。
什麼是樹
在計算器科學中,樹(英語:tree)是一種抽象資料型別(ADT)或是實現這種抽象資料型別的資料結構,用來模擬具有樹狀結構性質的資料集合。它是由n(n>0)個有限節點組成一個具有層次關係的集合。
樹的特點
- 每個節點有零個或多個子節點;
- 沒有父節點的節點稱為根節點;
- 每一個非根節點有且只有一個父節點;
- 除了根節點外,每個子節點可以分為多個不相交的子樹
術語
- 節點的度:一個節點含有的子樹的個數稱為該節點的度;
- 樹的度:一棵樹中,最大的節點的度稱為樹的度;
- 葉節點或終端節點:度為零的節點;
- 非終端節點或分支節點:度不為零的節點;
- 父親節點或父節點:若一個節點含有子節點,則這個節點稱為其子節點的父節點;
- 孩子節點或子節點:一個節點含有的子樹的根節點稱為該節點的子節點;
- 兄弟節點:具有相同父節點的節點互稱為兄弟節點;
- 節點的層次:從根開始定義起,根為第1層,根的子節點為第2層,以此類推;
- 深度:對於任意節點n,n的深度為從根到n的唯一路徑長,根的深度為0;
- 高度:對於任意節點n,n的高度為從n到一片樹葉的最長路徑長,所有樹葉的高度為0;
- 堂兄弟節點:父節點在同一層的節點互為堂兄弟;
- 節點的祖先:從根到該節點所經分支上的所有節點;
- 子孫:以某節點為根的子樹中任一節點都稱為該節點的子孫。
- 森林:由m(m>=0)棵互不相交的樹的集合稱為森林;
什麼是二叉樹
二叉樹:每個節點最多含有兩個子樹的樹稱為二叉樹;
完全二叉樹:對於一顆二叉樹,假設其深度為d(d>1)。除了第d層外,其它各層的節點數目均已達最大值,且第d層所有節點從左向右連續地緊密排列,這樣的二叉樹被稱為完全二叉樹;
滿二叉樹:所有葉節點都在最底層的完全二叉樹;
深度優先
深度優先遍歷即是先按深度來遍歷二叉樹,包括:
前序遍歷
遍歷順序 –> 根節點 -> 左子樹 -> 右子樹
中序遍歷
遍歷順序–> 左子樹 -> 根節點 -> 右子樹
後序遍歷
遍歷順序–> 左子樹 -> 右子樹 -> 根節點
首先,定義 TreeNode:
class TreeNode:
def __init__(self, value=None, left=None, right=None):
self.value = value
self.left = left # 左子樹
self.right = right # 右子樹
複製程式碼
例項化一個 TreeNode:
node1 = TreeNode("A",
TreeNode("B",
TreeNode("D"),
TreeNode("E")
),
TreeNode("C",
TreeNode("F"),
TreeNode("G")
)
)
複製程式碼
前序遍歷
def preTraverse(root):
if root is None:
return
print(root.value)
preTraverse(root.left)
preTraverse(root.right)
複製程式碼
執行結果:
A
B
D
E
C
F
G
複製程式碼
中序遍歷
def midTraverse(root):
if root is None:
return
midTraverse(root.left)
print(root.value)
midTraverse(root.right)
複製程式碼
執行結果:
D
B
E
A
F
C
G
複製程式碼
後序遍歷
def afterTraverse(root):
if root is None:
return
afterTraverse(root.left)
afterTraverse(root.right)
print(root.value)
複製程式碼
執行結果:
D
E
B
F
G
C
A
複製程式碼
廣度優先
廣度優先遍歷即是層次遍歷,按一層一層地遍歷。
def levelOrder(root):
# write your code here
res = []
# 如果根節點為空,則返回空列表
if root is None:
return res
# 模擬一個佇列儲存節點
q = []
# 首先將根節點入隊
q.append(root)
# 列表為空時,迴圈終止
while len(q) != 0:
length = len(q)
for i in range(length):
# 將同層節點依次出隊
r = q.pop(0)
if r.left is not None:
# 非空左孩子入隊
q.append(r.left)
if r.right is not None:
# 非空右孩子入隊
q.append(r.right)
res.append(r.value)
print(r.value)
return res
複製程式碼
執行結果:
A
B
C
D
E
F
G
複製程式碼
後記
這次複習先是到這裡了。這裡嘮叨一下,資料結構與算很重要,很多東西的實現都少不了資料結構與演算法,就如 mysql 的實現就用到了 B+ 樹,如果我們懂其中的原理,對資料庫效能優化會有很大的幫助。還有一點比較重要的是,大廠的面試肯定少不了演算法與資料結構。想進大廠?還是乖乖滴學通演算法。
本篇文章首發於公眾號「zone7」,關注公眾號獲取最新推文,後臺回覆【國慶指數】獲取原始碼。