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

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

using System;
using System.Collections.Generic;

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

        /// 
        /// 子节点
        /// 
        List Children { get; set; }
    }

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

        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 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    /// 
    /// 递归状态
    /// 
    public enum ERecursiveState
    {
        Finish,
        Next,
        Skip,
    }

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

        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);
    }

}

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

你可能感兴趣的:(c#,c#,.net,递归)