【力扣】589. N 叉树的前序遍历

题目概述

给定一个 N 叉树,返回其节点值的前序遍历 ,N叉树节点定义如下:

class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};

思考过程

递归法

树的遍历问题基本可以由递归实现,递归的实现需要考虑三点:

  1. 递归终止条件
  2. 递归的返回值
  3. 每一次递归需要处理的事

那么回到N叉树遍历,相比于二叉树,无非是根节点的个数由左右孩子变成了很多孩子,那么在N叉树遍历时,只需要考虑如何去除N个孩子即可,从Node定义可知,N个子孩子存储在一个vector数组中,那么主需要利用一个for循环即可取出N个孩子,代码如下:

   void dfs(Node* root, vector<int>& vt) {
       // 递归终止条件:为空则返回
       if (root == NULL) return ;
       // 每一次递归需要做的事:将当前节点的值加入到输出数组中
       // 返回值即为前序遍历结果:vt数组
       vt.push_back(root->val);
       vector<Node*> child = root->children;
       for(auto c:child) dfs(c, vt);
   }

   vector<int> preorder(Node* root) {
       vector<int> ans;
       dfs(root, ans);

       return ans;
   }

迭代法

同样从二叉树开始考虑,使用stack先进后出的特性即可实现前序遍历和后序遍历

  1. 首先考虑极端情况:根节点为空->直接返回空结果数组
  2. 创建一个stack用于存储将要处理的节点,首先将跟节点加入
  3. 使用while循环控制当stack不为空时,循环处理
  4. 创建一个指向当前节点(stack的栈顶元素)的Node指针,并将其节点值加入最终输出vector中,并从栈中删除栈顶元素
  5. 根据stack先进后出的特性,需要先加入当前节点的最后一个孩子,最后加入第一个孩子,才能在取出数据时达到前序遍历的要求

步骤5有两种实现方式,具体如代码

法一:使用两个栈
   vector<int> preorder(Node* root) {
       vector<int> vt;
       if (root == NULL) return vt;

       stack<Node*> node;
       node.push(root);
       while (!node.empty()) {
           Node* cur = node.top();
           node.pop();
           vt.push_back(cur->val);
           vector<Node*> child = cur->children;
           stack<Node*> temp;
           for (auto c:child) temp.push(c);
           while(!temp.empty()) {
               node.push(temp.top());
               temp.pop();
           }
       }

       return vt;
   }
法二:使用一个栈
   vector<int> preorder(Node* root) {
       vector<int>  vt;
       if (root == NULL) return vt;
       stack<Node*> st;
       st.push(root);
       while(!st.empty()) {
           Node* cur = st.top();
           st.pop();
           vt.push_back(cur->val);
           for(int i = cur->children.size() - 1; i >= 0; i--) {
               st.push(cur->children[i]);
           }
       }
       return vt;
   }
上一篇:linux性能优化基础——iommu相关配置


下一篇:基于ROS+CANopen的SocketCAN驱动在Ubuntu下的应用说明