中序遍歷(遞迴+迭代)
阿新 • • 發佈:2020-09-14
題目要求
給定一個二叉樹,返回它的中序 遍歷。
示例
輸入: [1,null,2,3]
1
\
2
/
3
輸出: [1,3,2]
進階: 遞迴演算法很簡單,你可以通過迭代演算法完成嗎?
解答:
迭代演算法可用棧儲存曾經路過的中序結點,回溯時可用bool型變數遮蔽對左子樹的訪問,避免發生死迴圈。
程式碼及分析註釋如下:
#include<iostream> #include<vector> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; //中序遍歷遞迴演算法 void inOrder(TreeNode* root, vector<int>& vi) { if (root != NULL) { inOrder(root->left, vi); vi.push_back(root->val); inOrder(root->right, vi); } } vector<int> inorderTraversal(TreeNode* root) { vector<int> vi; inOrder(root, vi); return vi; } //中序遍歷迭代演算法 vector<int> inOrderIteration(TreeNode* root) { vector<int> vi; vector<TreeNode *> stack; TreeNode* pT = root; bool backtrace = false;//回溯標誌 while (pT != NULL) { if (backtrace==false && pT->left != NULL) {//若存在左子樹,指標指向左子樹 stack.push_back(pT); pT = pT->left; }else{//不存在左子樹,先儲存當前值 backtrace = false;//設定回溯標誌為否 vi.push_back(pT->val); if (pT->right != NULL) {//若存在右子樹,指標指向右子樹 //stack.push_back(pT);-----------此時按理說應該不用入棧 pT = pT->right; }else {//若不存在右子樹,返回父節點 if (stack.empty() == false) {//若棧非空,取出棧頂元素 pT = stack.back(); stack.pop_back(); backtrace = true;//設定回溯標記為true,這樣便能不再訪問左子樹 } else//需要回溯,但棧已空,此時遍歷已結束 break; } } } return vi; } int main() { TreeNode a(1), b(2), c(3), d(4), e(5), f(6), g(7), h(8), i(9), j(10); a.left = &b; a.right = &e; b.left = &c; b.right = &d; d.right = &f; e.left = &g; e.right = &h; h.left = &i; i.right = &j; // auto vi = inorderTraversal(&a); auto vi = inOrderIteration(&a); for (auto i = vi.begin(); i != vi.end(); ++i) { cout << *i << "\t"; } }