树结构的深度遍历-前序遍历
树结构的深度遍历,本次介绍的是后序遍历方法。
介绍
后续遍历其实和前序遍历思路基本一致,唯一不同的是遍历路径是:子节点->父节点。
示例:

结果:[5,6,3,2,4,1]
代码
代码前提:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class Node { public int val; public IList<Node> children;
public Node() {}
public Node(int _val) { val = _val; }
public Node(int _val,IList<Node> _children) { val = _val; children = _children; } }
public IList<int> Postorder(Node root) { IList<int> list = new List<int>(); if(root == null){ return list; }
InOrder(root,list); return list; }
|
递归方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| private void InOrder(Node node,IList<int> list){
if(node == null){ return; }
if(node.children != null && node.children.Count > 0){ for(int i = 0; i < node.children.Count; i++){ InOrder(node.children[i],list); } } list.Add(node.val); }
|
迭代方案(1)
此迭代方案是模拟递归方式实现。
不过由于需要先遍历子节点,子节点结束后会再一次访问父节点,结点存在遍历两次的情况,所以需要一个数组记录已经遍历过子节点的结点。
这样如果结点已经遍历过子节点,那么就可以直接放心输出了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| private void InOrder(Node node,IList<int> list){
if(node == null){ return; } IList<Node> overNodes = new List<Node>(); Stack<Node> stack = new Stack<Node>(); stack.Push(node);
while(stack.Count > 0){ Node pNode = stack.Peek();
if(pNode.children == null || pNode.children.Count <= 0 || overNodes.Contains(pNode)){ stack.Pop(); list.Add(pNode.val); continue; }
if(pNode.children != null && pNode.children.Count > 0){ for(int i = pNode.children.Count - 1; i >= 0; i--){ stack.Push(pNode.children[i]); } } overNodes.Add(pNode); }
|
迭代方案(2)
该方法比较简单,后续遍历的结果其实与前序遍历相反,所以先按照前序遍历进行一次遍历,然后结果反转即可。
需要注意本次的前序遍历中,子节点的出栈顺序就必须是反序的了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| private void InOrder(Node node,IList<int> list){
if(node == null){ return; } Stack<Node> stack = new Stack<Node>(); stack.Push(node);
while(stack.Count > 0){ Node pNode = stack.Pop(); list.Add(pNode.val);
if(pNode.children != null && pNode.children.Count > 0){ for(int i = 0; i < pNode.children.Count; i++){ stack.Push(pNode.children[i]); } } }
((List<int>)list).Reverse(); }
|
该方案简单,而且性能也比较好,比较推荐这种写法。