C# 使用Queue<T>代替递归算法遍历树_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > C# 使用Queue<T>代替递归算法遍历树

C# 使用Queue<T>代替递归算法遍历树

 2017/11/15 12:03:39  我是伊只雄熊  程序员俱乐部  我要评论(0)
  • 摘要:递归时候每次调用自身在堆栈上要记录返回地址,而堆栈的空间很少,调用次数多了后会产生堆栈溢出,以下代码是实际项目中,通过Queue<T>来避免递归算法的代码:///<summary>///获取某个节点下特定属性的所有子孙节点///</summary>///<paramname="groupId"></param>///<returns></returns>publicIList<
  • 标签:C# 使用 遍历 递归 算法

    递归时候每次调用自身在堆栈上要记录返回地址,而堆栈的空间很少,调用次数多了后会产生堆栈溢出,以下代码是实际项目中,通过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 };
}

发表评论
用户名: 匿名