题目要求
给定一个二叉树,返回它的中序 遍历。
示例
输入: [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 << " ";
}
}