最近写代码碰到了一个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
bool result, object args)> 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<TNode>(
- IEnumerable
rootNodes, - Func
bool result, object args, IEnumerable 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);
- }
-
- }
也很久没写文章了,顺手记录一下。