題目要求
給定一個二叉樹,返回它的中序 遍歷。
示例
輸入: [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";
}
}