589. N 叉树的前序遍历
思路
栈的模拟,在下面的代码中写出了详细的注释。
代码
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
// 树的前序遍历,非递归写法
// curNode指向当前正在遍历的节点
// 到了curNode首先输出curNode->val
// 然后看看curNode是否存在孩子
// 如果存在孩子,那么curNode压入栈,curNode变成curNode->child
// 如果不存在孩子,取出栈顶元素
// 如果栈顶元素还有其它的孩子,curNode=curNode->其它孩子,(记录当前遍历)到的孩子的位置
// 如果没有其它孩子了,再重复取出栈顶元素
struct MyNode{
Node*node=NULL;
int pos=0;//指向当前遍历到哪一个孩子,pos这个地点的孩子还没有被遍历
MyNode(){}
MyNode(Node*_node,int _pos){
node=_node;
pos=_pos;
}
};
class Solution {
public:
stack<MyNode>sta;
vector<int>res;
vector<int> preorder(Node* root) {
if(root==NULL){
return vector<int>();
}
MyNode curMyNode(root,0);
sta.push(curMyNode); // 第一次入栈的时候记录结果
res.push_back(root->val); //
// cout<<"111"<<endl;
MyNode childMyNode; // 当前节点的孩子节点
while(!sta.empty()){
curMyNode=sta.top(); // 当前的节点
// cout<<curMyNode.node->val<<endl;
// 当前的节点如果是空节点
// if(curMyNode.node==NULL){
// sta.pop();
// continue;
// }
int &posChild=curMyNode.pos; //当前遍历到的孩子的位置
vector<Node*>&children=curMyNode.node->children;//当前的孩子节点的vector
if(posChild<children.size()){
// 栈顶的元素的遍历到的儿子的位置++
posChild++;
sta.pop();
sta.push(curMyNode);
// 准备好非空孩子节点并压入栈顺便记录结果
childMyNode.node=children[posChild-1];//刚刚posChild++了
childMyNode.pos=0;
if(childMyNode.node!=NULL){
sta.push(childMyNode);
res.push_back(children[posChild-1]->val);//第一次进栈压入值
}
continue;
}
else{
// 当前的遍历完了
sta.pop();
continue;
}
}
return res;
}
};