思路:栈可以改写任何递归。想清楚二叉树遍历所对应的栈操作,然后用额外的标记信息区分节点的状态就行了。具体的看代码注释吧。
/**
* Definition for a binary tree node.* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
struct DataNode{
TreeNode *node;
int state;//栈的元素额外标识
DataNode(TreeNode *p=NULL,int x=0):node(p),state(x){}
};
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if(root==NULL) return vector<int>();
vector<int> result;
stack<DataNode> tree_stack;
DataNode data_node(root,0);
tree_stack.push(data_node);
while(!tree_stack.empty()){
DataNode tem_data=tree_stack.top();
tree_stack.pop();
if(tem_data.state==0){//第一次遍历到一个节点的时候,输出,然后做下标记后继续压入栈,再把它的左孩子入栈。
if(tem_data.node!=NULL){//只有第一次需要判断节点是否为空,后面两种情况就不需要了
result.push_back(tem_data.node->val);
tem_data.state=1;
tree_stack.push(tem_data);
tree_stack.push(DataNode(tem_data.node->left,0));
}
}else if(tem_data.state==1){//第二次遍历到一个节点的时候,做下标记后继续压入栈,再把它的右孩子入栈。
tem_data.state=2;
tree_stack.push(tem_data);
tree_stack.push(DataNode(tem_data.node->right,0));
}else if(tem_data.state==2){//第三次遍历到一个节点的时候,说明该节点已经完成了它的使命,啥都不用做,让它出栈
//do nothing
}
}
return result;
}
};