/// <summary> /// 递归的查找子节点。此方法深度优先 /// </summary> /// <param name="parent"></param> /// <param name="predicate"></param> /// <returns></returns> protected BaseLeaf <TKey> FindChildren(BaseNode <TKey> parent, BaseLeaf <TKey> target, Func <BaseLeaf <TKey>, BaseLeaf <TKey>, bool> predicate) { // 传入节点检查(主要处理根节点) if (predicate(parent, target)) { return(parent); } foreach (var leaf in parent.ChildrenNodes.Foreach()) { // 如果有符合的子节点返回 if (predicate(leaf, target)) { return(leaf); } // 没有则去下层检查 // 去下层前检查一下是 node 再去 if (leaf is BaseNode <TKey> ) { var find_res = FindChildren(leaf as BaseNode <TKey>, target, predicate); if (find_res.NotNull()) { return(find_res); } } } return(null); }
protected BaseLeaf <TKey> FindNodeByName(string name, BaseLeaf <TKey> currNode) { if (currNode.IsNull()) { return(default(TNode)); } if (currNode.Name.Equals(name)) { return(currNode); } if (currNode is TNode) { var n = (TNode)currNode; if (n.ChildrenNodes.HasItem()) { foreach (var item in n.ChildrenNodes) { if (item.Name.Equals(name)) { return(item as BaseLeaf <TKey>); } } } } else { if (currNode.Name.Equals(name)) { return(currNode); } } return(default(TNode)); }
/// <summary> /// 定位路径字符串,/name/name 这种风格 /// 算法还需优化 /// </summary> /// <param name="pathStr"></param> /// <returns></returns> public BaseLeaf <TKey> LocationPath(string pathStr) { var pathArray = pathStr.Split('/'); BaseLeaf <TKey> thisNode = this.TreeRoot; if (pathArray.Any()) { for (var i = 0; i < pathArray.Length; i++) { if (i == 0 && pathArray[i].NullEmpty()) { continue; } if (pathArray[i].NotNullEmpty() && thisNode.NotNull()) { var nname = pathArray[i]; thisNode = FindNodeByName(nname, thisNode); if (thisNode.IsNull()) { break; } } } } return(thisNode); }
/// <summary> /// 查找目标节点, /// </summary> /// <param name="target"></param> /// <param name="predicate"></param> /// <returns></returns> public List <BaseNode <TKey> > FindParents(BaseLeaf <TKey> target, Func <BaseLeaf <TKey>, BaseLeaf <TKey>, bool> predicate) { var node = FindNode(target, predicate); List <BaseNode <TKey> > parents = new List <BaseNode <TKey> >(); ParentNode(node, parents); return(parents); }
/// <summary> /// 给一个node加入一个叶子 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="node"></param> /// <param name="newLeaf"></param> public static void AddLeaf <TKey>(this BaseNode <TKey> node, BaseLeaf <TKey> newLeaf) { if (node.ChildrenNull()) { node.ChildrenNodes = new List <BaseLeaf <TKey> >(); } node.ChildrenNodes.Add(newLeaf); }
/// <summary> /// 查找全部符合谓词条件的 叶子 /// 需提供对比对象 和 对比谓词 /// </summary> /// <param name="target"></param> /// <param name="predicate"></param> /// <returns></returns> public List <BaseLeaf <TKey> > FindAllLeaf(BaseLeaf <TKey> target, Func <BaseLeaf <TKey>, BaseLeaf <TKey>, bool> predicate) { List <BaseLeaf <TKey> > findLeafList = new List <BaseLeaf <TKey> >(); Func <BaseLeaf <TKey>, bool> p = (n) => n is BaseLeaf <TKey> && predicate(n, target); Action <BaseLeaf <TKey> > findAfter = (n) => findLeafList.Add(n); traversingTree(TreeRoot, p, findAfter); return(findLeafList); }
/// <summary> /// 获取父级 递归 /// </summary> /// <param name="child"></param> /// <param name="fathers"></param> private void GetFather(BaseLeaf <TKey> child, List <TNode> fathers) { TNode temp = Father(child); if (temp != null) { fathers.Add(temp); GetFather(temp as BaseLeaf <TKey>, fathers); } }
/// <summary> /// 返回叶子节点的字符形式 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="self"></param> /// <returns></returns> public static string Display <TKey>(this BaseLeaf <TKey> self) { if (self != null) { return($"{self.ID} - {self.PID} - {self.Name} - {self.NodeType}"); } else { return($"Object is null"); } }
private void ParentNode(BaseLeaf <TKey> currNode, List <BaseNode <TKey> > parents) { if (currNode.NotNull()) { if (currNode.Parent.NotNull()) { ParentNode(currNode.Parent, parents); } // 检查一下找到的是节点还是叶子,叶子不应该被加入父级层级组内 if (currNode is BaseNode <TKey> ) { parents.Add(currNode as BaseNode <TKey>); } } }
/// <summary> /// 数据源队列中寻找父节点 /// </summary> /// <param name="childNode"></param> /// <returns></returns> private TNode Father(BaseLeaf <TKey> childNode) { TNode temp = default(TNode); foreach (TNode n in SourceNodeList) { if (n.ID.Equals(childNode.PID)) { temp = n; break; } else { temp = default(TNode); } } return(temp); }
/// <summary> /// 查找相关节点信息,可能是节点,也可能是叶子 /// </summary> /// <param name="predicate"></param> /// <returns></returns> public BaseLeaf <TKey> FindNode(BaseLeaf <TKey> target, Func <BaseLeaf <TKey>, BaseLeaf <TKey>, bool> predicate) { return(FindChildren(TreeRoot, target, predicate)); }
/// <summary> /// 查找符合要求的叶子 /// </summary> /// <param name="target"></param> /// <param name="predicate"></param> /// <returns></returns> public BaseLeaf <TKey> FindLeaf(BaseLeaf <TKey> target, Func <BaseLeaf <TKey>, BaseLeaf <TKey>, bool> predicate) { Func <BaseLeaf <TKey>, BaseLeaf <TKey>, bool> newPredicate = (pt, tg) => pt is BaseLeaf <TKey> && predicate(pt, tg); return(FindChildren(TreeRoot, target, newPredicate)); }