思路
用一个栈来存放还没有遍历过的节点,并且保证栈内元素是中序的顺序,那么我们把所有元素都遍历一边的时候,就是栈为空的时候
按照中序遍历的要求,如果当前节点的左节点不为NULL,就把当前节点左节点存入,再移动到左节点,如果当前节点左节点为NULL,那么就把该节点的val存入数组,再将该节点从栈内出去(因为栈内只放未遍历的节点),再判断右节点,如果不为NULL,就将该节点移动到右节点处,再将节点存入栈,如果为NULL,就表明是一个孤立的节点,那么回到栈顶去取出元素节点,等效于回溯,并且要把节点的左节点置为NULL,不然会影响判断!!,这是该算法很不好的一点,因为会改变原有的树结构
代码
#include <stdio.h>
#include <vector>
#include <stack>
#include <iostream>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
void creat(TreeNode* &root) {//创建树
int m;
cin >> m;
if (m) {
TreeNode* t = new TreeNode(m);
root = t;
solve(root->left);
solve(root->right);
}
else {
return;
}
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> s;
TreeNode* t = root;
if (root == NULL) {
return v;
}
s.push(t);//t来表示当前节点,也就是栈顶节点
while (!s.empty()) {
if (t->left != NULL) {
t = t->left;
s.push(t);
continue;
}
v.push_back(t->val);
t = t->right;
s.pop();
if (t != NULL) {
s.push(t);
continue;
}
if (!s.empty())
{
t = s.top();
t->left = NULL;//非常关键,不加这个会有死循环
}
}
return v;
}
int main(void) {
vector<int> v;
TreeNode* root = NULL;
creat(root);
v = inorderTraversal(root);
}