- 正在學習的算法課程:《數據結構與算法之美》& “小甲魚數據結構”
- 傳送門: https://time.geekbang.org/column/126
- 新發現的寶貝1:https://pegasuswang.github.io/python_data_structures_and_algorithms/14_%E6%A0%91%E4%B8%8E%E4%BA%8C%E5%8F%89%E6%A0%91/tree/
- 新發現的寶貝2:https://www.bilibili.com/video/av17888939
- 代碼傳送門:https://github.com/Lebhoryi/Algorithms/tree/master/4.%E6%A0%91
- 二叉樹基本用鏈式存儲結構
- 2019/11/01
一、概念
- 樹結構是一種包括節點(nodes)和邊(edges)的擁有層級關係的一種結構
二、二叉樹
- 二叉樹是一種簡單的樹,它的每個節點最多隻能包含兩個孩子
其中,2是滿二叉樹,3是完全二叉樹
滿二叉樹一定是完全二叉樹,但是完全二叉樹不一定是滿二叉樹
三、二叉樹的表示 & 遍歷
3.1 二叉樹的表示
-
首先定義一個類表示節點
class Node(object): def __init__(self, val=None, left=None, right=None): self.val = val self.left = left self.right = right
class BinTree(obeject): def __init__(self): self.root = None
-
創建一棵樹
def add(self, elem): '''創建二叉樹''' node = Node(elem) # 如果根節點爲空,則elem作爲根節點 if not self.root: self.root = node return # 根節點入隊 queue = [self.root] while queue: # 父節點出隊 par_node = queue.pop(0) # 左節點不存在時,將elem 作爲左節點,否則左節點入隊 if not par_node.left: par_node.left = node return else: queue.append(par_node.left) # 右節點不存在時,將elem 作爲右節點,否則右節點入隊 if not par_node.right: par_node.right = node return else: queue.append(par_node.right)
3.2 二叉樹的遍歷
-
前序遍歷: 根節點->左子樹->右子樹
def pre_order(self, node): """前序遍歷""" if not node: return None print(node) self.pre_order(node.left) self.pre_order(node.right)
-
中序遍歷: 左子樹->根節點->右子樹
def mid_order(self, node): """中序遍歷""" if not node: return None self.mid_order(node.left) print(node) self.mid_order(node.right)
-
後序遍歷: 左子樹->右子樹->根節點
def post_order(self, node): """後序遍歷""" if not node: return None self.post_order(node.left) self.post_order(node.right) print(node)
-
層序遍歷(隊列實現)
def layer_order(self): """層序遍歷""" if not self.root: return None queue = [self.root] while queue: cur_node = queue.pop(0) print(cur_node) if cur_node.left: queue.append(cur_node.left) if cur_node.right: queue.append(cur_node.right)
-
完整代碼:
# coding=utf-8 ''' @ Summary: 遞歸遍歷二叉樹 @ Update: @ file: 4-1.二叉樹的遍歷.py @ version: 1.0.0 @ Author: [email protected] @ Date: 19-11-1 下午7:51 ''' import pysnooper class Node(object): def __init__(self, val): self.val = val self.left = None self.right = None def __repr__(self): return str(self.val) class BinTree(object): """二叉樹""" def __init__(self): self.root = None # @pysnooper.snoop(watch="queue") def add(self, elem): '''創建二叉樹''' node = Node(elem) # 如果根節點爲空,則elem作爲根節點 if not self.root: self.root = node return # 根節點入隊 queue = [self.root] while queue: # 父節點出隊 par_node = queue.pop(0) # 左節點不存在時,將elem 作爲左節點,否則左節點入隊 if not par_node.left: par_node.left = node return else: queue.append(par_node.left) # 右節點不存在時,將elem 作爲右節點,否則右節點入隊 if not par_node.right: par_node.right = node return else: queue.append(par_node.right) def layer_order(self): """層序遍歷""" if not self.root: return None queue = [self.root] while queue: cur_node = queue.pop(0) print(cur_node) if cur_node.left: queue.append(cur_node.left) if cur_node.right: queue.append(cur_node.right) def pre_order(self, node): """前序遍歷""" if not node: return None print(node) self.pre_order(node.left) self.pre_order(node.right) def mid_order(self, node): """中序遍歷""" if not node: return None self.mid_order(node.left) print(node) self.mid_order(node.right) def post_order(self, node): """後序遍歷""" if not node: return None self.post_order(node.left) self.post_order(node.right) print(node) if __name__=="__main__": tree = BinTree() for i in range(65,72): tree.add(chr(i)) # tree.layer_order() # tree.pre_order(tree.root) # tree.mid_order(tree.root) tree.post_order(tree.root)
四、代碼練習
- 左右反轉二叉樹
- 給定前序和後序構造二叉樹
- 驗證搜索二叉樹
- 二叉樹的最近公共祖先