tree traversal (樹的遍歷) - 中序遍歷 (inorder traversal) - 二叉樹的中序遍歷
1. tree traversal (樹的遍歷)
1.1 深度優先搜索 (depth-first search,DFS)
我們採用深度作爲優先級,從根節點開始一直到達某個確定的葉子節點,然後再返回根節點到達另一個分支。深度優先搜索策略可以根據根節點、左孩子樹和右孩子樹的相對順序被細分爲前序遍歷、中序遍歷和後序遍歷。
前序遍歷 (preorder traversal) - 中序遍歷 (inorder traversal) - 後序遍歷 (postorder traversal)
1.2 廣度優先搜索 - 寬度優先搜索 - 橫向優先搜索 (breadth-first search,BFS)
我們按照高度順序一層一層的訪問整棵樹,高層次的節點將會比低層次的節點先被訪問到。
下圖中的節點依照不同的策略遍歷,訪問的順序均爲 1, 2, 3, 4, 5
。寬度優先搜索劃分層次爲 [[1], [2, 3], [4, 5]]
。
2. 二叉樹的中序遍歷
給定一個二叉樹,返回它的前序遍歷。
輸入: [1,null,2,3]
1
\
2
/
3
輸出: [1,2,3]
int* preorderTraversal(struct TreeNode* root, int* returnSize)
輸入參數 root
爲 NULL
時,如果 return NULL
,*returnSize
必須設置爲 0
。
2.1 迭代實現 - 數組模擬棧 (stack) 的操作
從根節點開始,每次迭代彈出當前棧頂元素,並將其孩子節點壓入棧中,先壓入右孩子再壓入左孩子。輸出到最終結果的順序按照 Top -> Bottom 和 Left -> Right,符合前序遍歷的順序。
時間複雜度:訪問每個節點恰好一次,時間複雜度爲 O(N)
,其中 N
是節點的個數,即樹的大小。
空間複雜度:取決於樹的結構,最壞情況存儲整棵樹,空間複雜度是 O(N)
。
- 設置一個棧,將根節點 push 到棧中。
- 循環檢測棧是否爲空,若不空,則取出棧頂元素,保存其值。
- 查看棧頂元素
右子節點
是否存在,若存在則 push 到棧中。查看棧頂元素左子節點
,若存在,則 push 到棧中。 - 繼續回到
2.
執行,直到棧空。
3. 中序遍歷 (inorder traversal)
中序遍歷 (inorder traversal) 順着左側通路,自底而上依次訪問沿途各節點及其右子樹。
迭代式中序遍歷 (出棧節點以深色示意)