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个小组(一班一组,一班二组,二班一组,二班二组) *学校计算机教室有限,每一个小组分着来上课. *考试的时候大家一起考 *请 ...
随机推荐
- Squid 搭建正向代理服务器
Squid 是一款缓存代理服务器软件,广泛用于网站的负载均衡架构中,常见的缓存服务器还有varnish.ATS等. 正向代理服务器可满足内网仅有一台服务器可以上网,而要供内网所有机器上网的需求,也可以 ...
- VFIO简介 (转载)
VFIO简介 LTCChina | Nov 20 2013 | Comment (1) | Visits (15204) 概述 VFIO是一套用户态驱动框架,它提供两种基本服务: 向用户态提供访问硬件 ...
- 谁说delphi没有IOCP库,delphi新的IOCP类库,开源中
DIOCP Demo说明 下载地址 https://code.google.com/p/diocp/ 特地为DIOCP开设了一个群:320641073,欢迎学习的IOCP的童鞋进入讨论. 核心作者: ...
- Linux下文件的三种时间标记(atime ctime mtime)
在windows下,一个文件有:创建时间.修改时间.访问时间. 在Linux下,一个文件有:状态改动时间.修改时间.访问时间. 1)查看文件(或文件夹)的三种时间标记 (stat 命令) Access ...
- word2vec_训练模型
from gensim.models import Word2Vecfrom gensim.models.word2vec import LineSentence # 原始的训练语料转化成一个sent ...
- flask学习视频
https://study.163.com/course/courseMain.htm?courseId=1004091002 主要 https://www.cnblogs.com/senlinyan ...
- Predict the Winner LT486
Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...
- Android Studio Tip of the Day
1. Alt + Q 可以查看一个方法的简单参数列表. 2. 查看一个类,如果是eclipse的话,一般直接是F3, 现在的F3好痛苦.只能改为Ctrl + H,将就着用. 3. Ctrl + J 语 ...
- js实现环形菜单效果
点击中间的圆点,会弹出环形菜单,效果图: 代码: <!DOCTYPE html> <html> <head> <meta charset="UTF- ...
- c#中将字符串转换成带2位小数的浮点数
今天遇到一个展示酒店价格的需求,觉得是要显示成“¥0.00”样式的,就做个小随笔,将字符串装换成带2位小数的浮点数 代码如下 "; string amount = string.Empty; ...