###### tags: `LeetCode` `Recursion` `Postorder` `Iterative` `Medium` `Easy` `Tree` `Stack`
# LeetCode #590 [N-ary Tree Postorder Traversal](https://leetcode.com/problems/n-ary-tree-postorder-traversal/)
### (Easy):Recursion (Medium):Iterative
給定一個 N 元樹,返回其節點值的後序遍歷 。
N 元樹 在輸入中按層序遍歷進行序列化表示,每組子節點由空值 null 分隔(請參見示例)。
---
遞迴法:
很簡單, 先處理完子節點再將根節點的值放入數組。
```
class Solution {
public:
vector<int> postorder(Node* root) {
if(root==nullptr)return {};
vector<int> nodes;
helper(root, nodes);
return nodes;
}
void helper(Node* root, vector<int>& nodes){
if(root==nullptr)return;
for(Node* child:root->children)
helper(child, nodes);
nodes.push_back(root->val);
}
};
```
---
迭代法:
由於postorder的表示是左子節點->右子節點->根節點, 但是必須要先存取根結點才有辦法使用他的(左右)子節點, 這兩件事按照常理來說是衝突的(先pop出來的元素在最後表示時卻是在數組的尾端), 而解決衝突的辦法就是數組反著插入, 由末端插入變成前端插入, 這樣最早插入的數會在數組的尾端。
而由於postorder的子節點表現先後順序為左至右, 以常理來說堆疊插入應該先右後左(也就是root->children[root->children.size()-1]往root->children[0])插入, 但由於輸出反向了, 所以堆疊的插入也變為先左後右。
```
class Solution {
public:
vector<int> postorder(Node* root) {
if(root){
stack<Node*> s;
vector<int> nodes;
s.push(root);
while(!s.empty()){
Node* cur=s.top();s.pop();
nodes.insert(nodes.begin(), cur->val);
for(int i=0;i<cur->children.size();i++){
s.push(cur->children[i]);
}
}
return nodes;
}
return {};
}
};
```