C# 使用Queue<T>代替递归算法遍历树
递归时候每次调用自身在堆栈上要记录返回地址,而堆栈的空间很少,调用次数多了后会产生堆栈溢出,以下代码是实际项目中,通过Queue<T>来避免递归算法的代码:
/// <summary>
/// 获取某个节点下特定属性的所有子孙节点
/// </summary>
/// <param name="groupId"></param>
/// <returns></returns>
public IList<OfficeGroupNodeDto> GetSelfAndChildOfficesByGroupId(int groupId)
{
Func<int, string, BusinessType, int, string, OfficeGroupNodeDto> createGroupNodeFunc =
(id, name, bizType, parentId, parentName) =>
new OfficeGroupNodeDto()
{
OfficeId = id,
Name = name,
BizType = bizType,
ParentId = parentId,
ParentName = parentName
};
var offices = GetTenantOffices().ToArray();
Func<int, OfficeDto[]> getChildOfficesFunc = id => offices.Where(x => x.ParentId == id).ToArray();
//创建队列
var groupNodeCacheQueue = new Queue<OfficeGroupNodeDto>();
var currentGroup = groupId == 0 || groupId == Office.AdminOffice.Id
? ToDto(Office.AdminOffice)
: offices.FirstOrDefault(x => x.Id == groupId && x.OfficeType == OfficeType.Group);
if (currentGroup == null) return null;
var officeGroupNodeDto =
createGroupNodeFunc(currentGroup.Id, currentGroup.Abbreviation, currentGroup.BizType, 0, string.Empty);
//初始进入队列一个元素
groupNodeCacheQueue.Enqueue(officeGroupNodeDto);
//循环读取队列内元素,直到读取完
while (groupNodeCacheQueue.Count > 0)
{
//出队列一个元素节点
var currentGroupNode = groupNodeCacheQueue.Dequeue();
//获取该节点的所有孩子节点
var childOffices = getChildOfficesFunc(currentGroupNode.OfficeId);
currentGroupNode.IsGroup = true;
var hasChildren = childOffices.SafeAny();
currentGroupNode.HasChildren = hasChildren;
if (!hasChildren) continue;
//遍历当前节点的孩子节点
foreach (var office in childOffices)
{
if (office.BizType == BusinessType.FranchiseChain) continue;
//创建符合条件的节点
var newNode = createGroupNodeFunc(office.Id, office.Abbreviation, BusinessType.RegularChain,
currentGroupNode.OfficeId, currentGroupNode.Name);
currentGroupNode.Items.Add(newNode);
if (office.OfficeType == OfficeType.Office) continue;
//把还有子节点的孩子元素节点到队列,待下次循环继续
groupNodeCacheQueue.Enqueue(newNode);
}
}
return new List<OfficeGroupNodeDto>() { officeGroupNodeDto };
}
注:主要看注释部分的总体思路,其他次要细节不用太关注
当然这里也可以用其他数据结构如Stack<T>,根据实际需要选择,如有没有顺序要求。
C# 使用Queue<T>代替递归算法遍历树的更多相关文章
- POJ 1849 Two(遍历树)
POJ 1849 Two(遍历树) http://poj.org/problem?id=1849 题意: 有一颗n个结点的带权的无向树, 在s结点放两个机器人, 这两个机器人会把树的每条边都走一遍, ...
- Java集合的Stack、Queue、Map的遍历
Java集合的Stack.Queue.Map的遍历 在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一 ...
- lintcode :前序遍历和中序遍历树构造二叉树
解题 前序遍历和中序遍历树构造二叉树 根据前序遍历和中序遍历树构造二叉树. 样例 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: 2 / \ 1 3 注意 你可以假设树中不存 ...
- lintcode: 中序遍历和后序遍历树构造二叉树
题目 中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: 2 / \ 1 3 注意 你可 ...
- java遍历树(深度遍历和广度遍历
java遍历树如现有以下一颗树:A B B1 B11 B2 B22 C C ...
- LintCode-72.中序遍历和后序遍历树构造二叉树
中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 注意事项 你可以假设树中不存在相同数值的节点 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: ...
- LintCode-73.前序遍历和中序遍历树构造二叉树
前序遍历和中序遍历树构造二叉树 根据前序遍历和中序遍历树构造二叉树. 注意事项 你可以假设树中不存在相同数值的节点 样例 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: ...
- 问题:Oracle 树形遍历;结果:使用oracle进行遍历树操作
使用oracle进行遍历树操作 1:首先数据库中表必须是树形结构的 2:super_department_id 为 department_id 的父节点编号 3:以下语句的执行结果是:depart ...
- js39---组合模式,查找遍历树
/** *有这样一个需求 *有一个学校有2个班(一班,二班) *每个班级分2个小组(一班一组,一班二组,二班一组,二班二组) *学校计算机教室有限,每一个小组分着来上课. *考试的时候大家一起考 *请 ...
随机推荐
- LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图
#6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- 大牛的距离(笑cry)精简算法
在一条数轴上有N头牛在不同的位置上,每头牛都计算到其它各头牛的距离.求这n*(n-1)个距离的总和.1<= N <= 10000.每头牛所在位置是一个范围在0到1,000,000,000之 ...
- mongo数据库的y2038问题
查阅mongo for c driver 驱动源码, 发现其 _id 是 12byte ,其中头4字节,调用time(NULL), 这个函数存在y2038问题. 建议是修改为16byte ,前面8b ...
- spring converter-message 规则
spring 判断返回值使用哪个 converter 时,会执行两次converter 循环.. 第一次会根据 返回类型(converter的support方法) 和 mediaType 遍历所有co ...
- Django 自定义模板标签TemplateTags
创建自定义的模板标签(template tags) Django提供了以下帮助函数(functions)来允许你以一种简单的方式创建自己的模板标签(template tags): simple_tag ...
- LD_LIBRARY_PATH
LD_LIBRARY_PATH是Linux环境变量名,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径. 在linux下可以用export命令来设置这个值,比如 在linux ...
- Keras的泰坦尼克号的生存率的数据分析
# coding: utf-8 # In[1]: import urllib.request import os # In[2]: url="http://biostat.mc.vand ...
- kbmmw 5.05.00 发布
新年前最后几天,kbmmw 发布了新版本,增加一大波功能.we are happy to announce v5.05.50 of our popular middleware for Delphi ...
- 使用小技巧加快IDEA的开发速度
一.live template的使用. 1.live template(自定义模板的载入)打开: Ctrl+shift+A 再在命令行中间输入live template弹出用户自定义的界面.需要自行 ...
- 812. Largest Triangle Area
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...