栈模拟函数递归基础方法

本文介绍了一种不依赖额外标记的深度优先遍历方法。通过使用栈并倒序压入子节点来确保深度优先顺序,巧妙地实现了目标节点的查找。

如果说,

节点可以自带一个是否被遍历的描述字段;

或外部有一个dic存储已经被遍历过的节点的;

那么都很好实现没什么好说的。

下面是一种不需要上述两种操作的遍历方式,有点巧妙

直接上代码

static Stack<Transform> m_transStack = new Stack<Transform>();
public static Transform GetTrans(Transform parentTrans, string needTransName)
{
    if (parentTrans == null || string.IsNullOrEmpty(needTransName))
    {
        return parentTrans;
    }
    m_transStack.Clear();
    m_transStack.Push(parentTrans);
    Transform trans = null;
    while (m_transStack.Count > 0)
    {
        trans = m_transStack.Pop();
        var cTrans = trans.Find(needTransName);
        if (cTrans != null)
        {
            return cTrans;
        }
        for (int i = trans.childCount - 1; i >= 0; i--)
        {    
            m_transStack.Push(trans.GetChild(i));
        }
    }
    return null;
}

上面代码从的事情就是从指定的父节点开始,深度优先去找名字为needTransName的节点。

巧妙的地方在于,

当节点从栈pop出来之后,直接把该节点的所有子节点倒序push到栈中。

这样处理为什么可以模仿深度优先呢?

第一,正常按照文章开头那两种方式去遍历的话,都是要等到某个节点的所有子节点都被遍历完了,这个节点才能出栈。

但是这里不用,它直接把所有子节点都塞进去了,我一开始乍一看还以为是层次遍历(但要用队列才是层次),其实并不是,

所有节点塞进去就能保证是按深度优先方式遍历了吗?要看顺序。

第二,push的顺序,把某节点所有子节点按倒序push进栈,这样就能保证了深度优先遍历。

上述两点做法的意义在于,遍历一个节点之后,把他之后所有子节点的遍历顺序都决定好(深度优先)放入栈中等待遍历就行。

细细想想会发现很巧妙,所以记录下来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值