遞迴法求解三種遍歷方式是十分簡單的,但迭代法卻不太簡單,本文給出幾種方式和模板。
節點型別
struct treenode
};
題目
前序遍歷是中左右的循序,根據棧的先入後出的特點,入棧的順序跟遍歷的順序相反,這樣出棧的時候就可以得到想要的順序。
遞迴思路:先樹根,然後左子樹,然後右子樹。每棵子樹遞迴。
在迭代演算法中,思路演變成,每到乙個節點 a,就應該立即訪問它。
因為,每棵子樹都先訪問其根節點。對節點的左右子樹來說,也一定是先訪問根。在 a 的兩棵子樹中,遍歷完左子樹後,再遍歷右子樹。因此,在訪問完根節點後,遍歷左子樹前,要將右子樹壓入棧。
class
solution
return result;}}
;
題目
我們可以用與前序遍歷相似的方法完成後序遍歷。後序遍歷與前序遍歷相對稱。
思路:每到乙個節點 a,就應該立即訪問它。 然後將左子樹壓入棧,再次遍歷右子樹。
因為前序為中左右,上述完成後為中右左,結果逆序為左右中(後序遍歷)
遍歷完整棵樹後,結果序列逆序即可。
class
solution
reverse
(result.
begin()
, result.
end())
;return result;}}
;
題目
思路:每到乙個節點 a,因為根的訪問在中間,將 a 入棧。然後遍歷左子樹,接著訪問 a,最後遍歷右子樹。
在訪問完 a 後,a 就可以出棧了。因為 a 和其左子樹都已經訪問完成。
class
solution
if(st.
size()
)}return result;}}
;
原文
思路:我們需要乙個標誌區分每個遞迴呼叫棧,這裡使用nullptr來表示,代表要處理的節點。
剛剛在迭代的過程中,其實我們有兩個操作,乙個是處理:將元素放進result陣列中,乙個是訪問:遍歷節點。
為什麼剛剛寫的前序遍歷的**,不能和中序遍歷通用呢,因為前序遍歷的順序是中左右,要先訪問的元素是中間節點,要處理的元素也是中間節點,所以剛剛才能寫出相對簡潔的**,因為要訪問的元素和要處理的元素順序是一致的,都是中間節點。
但中序遍歷不是,這就造成了處理順序和訪問順序是不一致的。所以在改進方法裡用nullptr標記要處理的結點
前序遍歷
class
solution
else
}return res;}}
;
後序遍歷
class
solution
else
}return res;}}
;
中序遍歷
class
solution
else
}return res;}}
;
二叉樹前中後序遍歷迭代實現
二叉樹遍歷迭代實現 迭代用棧實現 遞迴的原理就是棧,每次呼叫乙個方法就會開闢乙個棧幀,而每個棧幀的返回順序也是按照後進先出的順序。所以基於這個原理,任何遞迴能解決的問題都可以轉換為迭代去實現。只需記住一點 棧是先進後出。前序是根 左 右,那麼棧的入棧順序是根 此時進行出棧操作並新增到結果 右 左 中...
二叉樹前中後序遍歷
前序遍歷a b d f g h i e c 中序遍歷f d h g i b e a c 後序遍歷f h i g d e b c a 前序 根左右 中序 左根右 後序 左右根 已知某二叉樹的前序遍歷為a b d f g h i e c,中序遍歷為f d h g i b e a c,請還原這顆二叉樹。思...
二叉樹前中後序遍歷
二叉樹 6.先序遍歷 10分 請編寫遞迴函式,實現二叉樹的先序遍歷。函式原型 先序遍歷 void bintreepreorder const tnode root 說明 root為二叉樹或子樹的根指標。在標頭檔案 bintree.h 新增函式宣告。bintree.h 先序遍歷 void bintre...