【二叉树】非递归遍历方法

1.事情起因

刷力扣到了二叉树遍历算法部分,递归方法实在太简单了,对应三种前中后序为:

  • 前:根左右
  • 中:左根右
  • 后:左右根

但是发现时间复杂度很高,递归开辟隐式栈空间导致的,所以研究了下使用“迭代”方法,自己显示开辟一个栈空间来实现,结果不错,很大程度提高了计算速度。我是一名Unity程序,所以使用C#。

2.二叉树遍历通过迭代实现

三种前中后序迭代实现方式思路均略有不同,所以在此记录下来。

2.1 前序遍历(迭代法)

思路(根左右):

  • 开辟一个辅助栈空间,根入栈,顶出栈进行操作输出,右左入栈(为什么?因为右左入,左右出,符合前序的顺序)。以此遍历直到空栈结束。
public IList<int> PreorderTraversal(TreeNode root)
{
    IList<int> t = new List<int>();
    if (root == null)
        return t;
    Stack<TreeNode> s = new Stack<TreeNode>();
    s.Push(root);
    while (s.Count > 0)
    {
        TreeNode n = s.Pop();
        t.Add(n.val);
        if (n.right != null)
            s.Push(n.right);
        if (n.left != null)
            s.Push(n.left);
    }
    return t;
}

2.2 中序遍历(迭代法)

思路(左根右):

  • 中序遍历并非简单调整代码顺序就能实现,因为遍历顺序与操作输出的顺序不一致,所以需采用自顶向下找最左叶子结点,然后向上,之后再出栈处理右节点。
public IList<int> PrecenterTraversal(TreeNode root)
{
    IList<int> t = new List<int>();
    if (root == null)
        return t;
    Stack<TreeNode> s = new Stack<TreeNode>();
    s.Push(root);
    TreeNode r = root;
    while (r != null && s.Count > 0)
    {
        if (r != null)
        {
            s.Push(r);
            r = r.left;
        }
        else
        {
            r = s.Pop();
            t.Add(r.val);
            r = r.right;
        }
    }
    return t;
}

2.3 后序遍历(迭代法)

思路(左右根):

  • 后序遍历可以在前序遍历的基础之上变种,前序入栈操作顺序为根右左,调整为根左右,则输出顺序就是根右左,再对输出结果Reverse,就变成目标的左右根顺序了。
  • 重申一下:根右左、根左右(这是入栈顺序),对应出栈顺序为根左右、根右左(这是操作输出顺序),那么反转根右左,就变成了左右根。
public IList<int> PostorderTraversal(TreeNode root)
{
    List<int> t = new List<int>();
    if (root == null)
        return t;
    Stack<TreeNode> s = new Stack<TreeNode>();
    s.Push(root);
    while (s.Count > 0)
    {
        TreeNode n = s.Pop();
        t.Add(n.val);
        if (n.left != null)
            s.Push(n.left);
        if (n.right != null)
            s.Push(n.right);
    }
    t.Reverse();
    return t;
}

3.优化结果

  • 从力扣提交记录上看,耗时排名上升幅度很大
    递归迭代
    耗时排名战胜14%战胜98%

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值