迭代实现二叉树遍历
之前看过一个算法,但没理解,这次用了一个自己的算法;
整个过程有点像是状态转移,标识了三种状态:
1. 第一次入栈,标识为NORMALREAD状态
2. 访问左子树,标识为BACKFROMLETF状态,
3. 访问右子树,标识BACKFROMRIGHT状态
下面已经通过测试
class Solution {
public:
enum state{NORMALREAD = 0, BACKFROMLEFT = 1, BACKFROMRIGHT = 3}; // 三种状态
typedef pair<TreeNode*,state> TreePair; // 结点与状态一起标识
inline void changeState(stack<TreePair>& stk, state sta) // 实现栈顶元素的状态转移
{
TreePair TP = stk.top();
stk.pop();
stk.push(make_pair(TP.first,sta));
return;
}
vector<int> postorderTraversal(TreeNode *root) {
TreePair TP;
stack<TreePair> stk;
vector<int> vec;
TreeNode* node;
if(!root) return vec; // 空结点
else if(root->left ==NULL && root->right == NULL) // 只有根结点
{
vec.push_back(root->val);
return vec;
}
// 多于一个结点
stk.push(make_pair(root,NORMALREAD)); // 根结点以N状态入栈
while(!stk.empty())
{
TP = stk.top(); // 取出栈顶元素
node = TP.first;
if (TP.second == NORMALREAD) // N状态,左子树没有访问过
{
changeState(stk,BACKFROMLEFT); // 向左下访问,转移当前结点状态为L
if (node->left != NULL)
stk.push(make_pair(node->left,NORMALREAD));
}
else if(TP.second == BACKFROMLEFT) // L状态左边访问过,右子树没有访问
{
changeState(stk,BACKFROMRIGHT); // 将向右子树访问,当前结点状态转移成R状态
if(node->right != NULL) // 右不为空
stk.push(make_pair(node->right,NORMALREAD));
}
else if(TP.second == BACKFROMRIGHT) // 右边已经访问,直接输出当前结点;
{
// cout<<node->val<<endl;
vec.push_back(node->val);
stk.pop(); // 删除栈顶元素
}
}
return vec;
}
};