c# 用非递归的写法实现递归

最近写代码碰到了一个bug,就是递归次数太多爆堆栈了,然后就写了一个递归工具来解决这个问题。

using System;
using System.Collections.Generic;

/// <summary>
/// 递归工具
/// </summary>
public static class RecursionTool
{
    //递归方式 1 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    /// <summary>
    /// 树节点接口
    /// </summary>
    public interface ITreeNode
    {
        /// <summary>
        /// 访问标记
        /// </summary>
        bool Visited { get; set; }

        /// <summary>
        /// 子节点
        /// </summary>
        List<ITreeNode> Children { get; set; }
    }

    /// <summary>
    /// 递归算法的非递归实现
    /// 以节点树的方式递归
    /// </summary>
    public static (bool result, object args) Recursive(
        IEnumerable<ITreeNode> rootNodes,
        Func<ITreeNode, (bool result, object args)> handleNode)
    {
        var stack = new Stack<ITreeNode>();

        foreach (var item in rootNodes)
        {
            item.Visited = false;
            stack.Push(item);
        }

        while (stack.Count > 0)
        {
            var rootNode = stack.Peek();
            //没访问过,且有子节点时
            if (rootNode.Visited == false && rootNode.Children != null && rootNode.Children.Count > 0)
            {
                rootNode.Visited = true;
                //把子节点全部入栈
                foreach (var item in rootNode.Children)
                {
                    item.Visited = false;
                    stack.Push(item);
                }
            }
            //访问处理根节点
            else
            {
                rootNode = stack.Pop();
                rootNode.Visited = false;

                if (handleNode != null)
                {
                    var tuple = handleNode(rootNode);
                    if (tuple.result)
                    {
                        return tuple;
                    }
                }
            }
        }

        return (false, null);
    }


    //递归方式 2 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    /// <summary>
    /// 递归状态
    /// </summary>
    public enum ERecursiveState
    {
        Finish,
        Next,
        Skip,
    }

    /// <summary>
    /// 递归算法的非递归实现
    /// 根据回调里的逻辑递归
    /// </summary>
    public static (bool result, object args) Recursive<TNode>(
        IEnumerable<TNode> rootNodes,
        Func<TNode, (ERecursiveState state, bool result, object args, IEnumerable<TNode> nexts)> handleNode)
    {
        var stack = new Stack<TNode>();

        foreach (var item in rootNodes)
        {
            stack.Push(item);
        }

        while (stack.Count > 0)
        {
            var rootNode = stack.Pop();

            if (handleNode != null)
            {
                var tuple = handleNode(rootNode);
                switch (tuple.state)
                {
                    case ERecursiveState.Finish:
                        return (tuple.result, tuple.args);

                    case ERecursiveState.Next:
                        {
                            if (tuple.nexts != null)
                            {
                                foreach (var item in tuple.nexts)
                                {
                                    stack.Push(item);
                                }
                            }
                        }
                        break;
                }
            }
        }

        return (false, null);
    }

}

也很久没写文章了,顺手记录一下。

猜你喜欢

转载自blog.csdn.net/WPAPA/article/details/133797537