1 二叉樹的理論基礎
文章連結:程式碼隨想錄
影片連結:關於二叉樹,你該瞭解這些!| 二叉樹理論基礎一網打盡,二叉樹的種類、二叉樹的儲存方式、二叉樹節點定義、二叉樹的遍歷順序_嗶哩嗶哩_bilibili
1.1 二叉樹的種類
- 滿二叉樹
所有節點處的值都排滿了,沒有空的
- 完全二叉樹
只有在最後一層的時候,從左至右是順序儲存,且空的位置只能在右邊,左邊不能有空的
- 二叉搜尋樹
這種就是滿足左邊數值中滿足所有數值都小於根節點數,右邊的數值滿足所有數值都大於根節點數
- 平衡二叉搜尋樹
滿足二叉搜尋樹的基本要求後,其左右節點的高度差不超過1
1.2 二叉樹的儲存方式
鏈式儲存和順序儲存
- 鏈式儲存
這種方式就是相當於之前學的連結串列一樣,每一個值擁有左指標和右指標,最後一層的左右指標指向空位置即可
- 順序儲存
就相當於陣列的儲存,先儲存父節點,然後在儲存子節點,一步一步下來
1.3 二叉樹的遍歷方式
深度遍歷和廣度遍歷
- 深度遍歷
這種是先向下遍歷;這個分為三種:前序遍歷,中序遍歷和後續遍歷;前序遍歷是中左右,中序遍歷是左中右,後續遍歷是左右中;這個前後的順序其實是指中節點在哪個位置
- 廣度遍歷
這種方式就是橫著遍歷的,就可以使用了
1.4 二叉樹的定義方式
這個定義就是需要定義一個值,和左右節點,即指標即可
class TreeNode:
def __init__(self,val,left=None,right=None):
self.val = val
self.left = left
self.right = right
2 二叉樹的遞迴遍歷
文章連結:程式碼隨想錄
影片連結:每次寫遞迴都要靠直覺? 這次帶你學透二叉樹的遞迴遍歷!| LeetCode:144.前序遍歷,145.後序遍歷,94.中序遍歷_嗶哩嗶哩_bilibili
自己的思路:害,這種題真的就是,一看就會,一做就廢
2.1 遞迴演算法的三部曲
- 確定遞迴函式的引數和返回值
- 確定終止條件
- 確定單層遞迴的邏輯
2.2 遞迴的三道題
每次新增的值都是中序的值,其他的就向下遍歷
思考:為什麼不是左的值和右的值?
因為左和右的值她的下面還有下一層值,無限迴圈,,,
2.2.1 前序遍歷
題目連結:144. 二叉樹的前序遍歷 - 力扣(LeetCode)
前序的順序是中左右,所以先新增中序的值,遇到左右繼續遍歷
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result = []
def res(node):
if node == None:
return
result.append(node.val)
res(node.left)
res(node.right)
res(root)
return result
2.2.2 中序遍歷
題目連結:94. 二叉樹的中序遍歷 - 力扣(LeetCode)
中序遍歷是左中右的順序,按照這個往下寫就行
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result = []
def dfs(node):
if node == None:
return
dfs(node.left)
result.append(node.val)
dfs(node.right)
dfs(root)
return result
2.2.3 後序遍歷
題目連結:145. 二叉樹的後序遍歷 - 力扣(LeetCode)
後序遍歷過程中,其內部的結構為左右中
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result = []
def dfs(node):
if node == None:
return
dfs(node.left)
dfs(node.right)
result.append(node.val)
dfs(root)
return result
2.3 本題小結
- 從這道題來理解的話,會發現遞迴不難,但是自己去寫邏輯還是有轉不過來的時候
- 主要就是函式呼叫的時候會很吃力,不知道為什麼
3 二叉樹的層序遍歷思路
文章連結:程式碼隨想錄
影片連結:講透二叉樹的層序遍歷 | 廣度優先搜尋 | LeetCode:102.二叉樹的層序遍歷_嗶哩嗶哩_bilibili
3.1 層序遍歷的解題思路
- 首先判斷整個結尾有沒有空,空的話就返回一個空列表
- 對其進行層序遍歷,首先是將其值全部儲存到佇列中,然後一個個彈出,增加現在的位置的值,最終進行值返回
3.2 leetcode102.二叉樹的層序遍歷
題目連結:102. 二叉樹的層序遍歷 - 力扣(LeetCode)
3.2.1 佇列的方法
import collections
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if root == None:
return []
queue = collections.deque([root])
result =[]
while queue:
level =[]
for _ in range(len(queue)):
cur = queue.popleft()
level.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result.append(level)
return result
3.2.2 遞迴的方法
import collections
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if root == None:
return []
result =[]
def dfs(node,level):
if node ==None:
return
if len(result)==level:
result.append([])
result[level].append(node.val)
dfs(node.left,level+1)
dfs(node.right,level+1)
dfs(root,0)
return result
3.3 leetcode 107二叉樹的層序遍歷 II
題目連結:107. 二叉樹的層序遍歷 II - 力扣(LeetCode)
3.2.1 佇列的方法
其實將上一道題進行一個倒序就好了
import collections
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
if root == None:
return []
queue = collections.deque([root])
result = []
while queue:
level = []
for _ in range(len(queue)):
cur = queue.popleft()
level.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result.append(level)
return result[::-1]
3.2.2 遞迴的方法
import collections
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
if root == None:
return []
result = []
def dfs(node,level):
if node == None:
return
if len(result) == level:
result.append([])
result[level].append(node.val)
dfs(node.left,level+1)
dfs(node.right,level+1)
dfs(root,0)
return result[::-1]
4 今日小結
- 怎麼說呢,感覺今天的題,學起來很容易,就是一學就會,但是一做就廢
- 內容上理解挺容易的,但是感覺因為佇列掌握不是很好,其實做就沒這麼容易了