第一篇如何从树叶层开始建树?算法其实是有问题的,它要求完整的树形结构结构(也就是所有节点都显示的树)的树叶节点在同一高度,否则就会有问题。
例如如下的树形就会出问题。
如果出现这种情况如何实现第一篇中业务逻辑呢?
前提条件是知道所有的树节点,如何只显示满足一定条件的叶节点组成的树呢?
此处为了简化,改为显示树叶节点标示为奇数的叶节点组成的树。
前提条件:
1知道树的所有节点
2知道满足条件的树叶节点(也就是树叶节点标示为奇数的叶节点)
如何建立如下的树形结构:
对于上图的树最总显示应该为:
显然,使用第一篇文章的算法有问题。
如果使用从树叶节点开始建树,就会涉及如何合并同一个父节点的子节点问题?
思考了很长时间,竟然发现,这种思路很难实现,如果实现,算法也非常复杂。
因为非常熟悉从根节点开始建树的算法,如果能获取到最终显示的所有节点(也就是去掉不需要的节点集合),那么就可以使用从根节点开始建树的算法。
因此思路就是
1获取所有需要的节点(去掉不需要的节点)
2从根节点开始建树
最终代码:
/// <summary>
/// 返回需要的树
/// </summary>
/// <param name="listAllNodes">树的所有节点,包含不需要显示的节点</param>
/// <param name="dicNodes">键为节点编号,值为节点,初始为需要显示的叶节点</param>
/// <returns></returns>
public static List<TreeNode> GeTree(List<TreeNode> listAllNodes, Dictionary<int, TreeNode> dicNodes)
{
Dictionary<int, TreeNode> listAllRootNodes = new Dictionary<int, TreeNode>();//保存需要的所有节点
List<TreeNode> leafNodes = new List<TreeNode>();
leafNodes.AddRange(dicNodes.Values);
foreach (TreeNode node in leafNodes)//遍历叶节点,
{
GetAllNodes(listAllNodes, node.ParentID.Value, ref listAllRootNodes, ref dicNodes);
}
List<TreeNode> allNode = new List<TreeNode>();
allNode.AddRange(dicNodes.Values);//所有需要显示的节点,树的根节点没有包含在其中
foreach (TreeNode node in listAllRootNodes.Values)//遍历根节点
{
List<TreeNode> childnodes = GetAllChildNodes(allNode, node);
node.children = childnodes;
}
List<TreeNode> AllRootNodes = new List<TreeNode>();
AllRootNodes.AddRange(listAllRootNodes.Values);//所有需要显示的节点,树的根节点没有包含在其中
return AllRootNodes;
}
/// <summary>
/// 递归,得到所有需要的的根节点,和所有需要其他的节点
/// </summary>
/// <param name="listAllTreeNodes">树的所有节点,包含不需要的节点</param>
/// <param name="nodeId"></param>
/// <param name="listAllRootNodes">保存树的根节点</param>
/// <param name="dicNode">键为节点编号,值为节点,包含所有需要的节点</param>
private static void GetAllNodes(List<TreeNode> listAllTreeNodes, int nodeId, ref Dictionary<int, TreeNode> listAllRootNodes, ref Dictionary<int, TreeNode> dicNode)
{
foreach (TreeNode item in listAllTreeNodes)
{
if (item.ID == nodeId)
{
if (item.ParentID.HasValue)//存在父节点
{
int parentId = item.ParentID.Value;
if (!dicNode.ContainsKey(nodeId))//此节点没有添加
{
dicNode.Add(nodeId, item);
}
if (!dicNode.ContainsKey(parentId))//此节点没有添加
{
GetAllNodes(listAllTreeNodes, parentId, ref listAllRootNodes, ref dicNode);
}
}
else//不存在父节点,也就是根节点
{
if (!listAllRootNodes.ContainsKey(nodeId))//此节点没有添加
{
listAllRootNodes.Add(nodeId,item); //把此节点添加入根节点的集合
}
}
}
}
}
/// <summary>
/// 返回某个节点的子节点
/// </summary>
/// <param name="listAllTreeNodes">所有需要显示的节点</param>
/// <param name="parentNode">父节点</param>
private static List<TreeNode> GetAllChildNodes(List<TreeNode> listAllTreeNodes, TreeNode parentNode)
{
List<TreeNode> ChildNodes = new List<TreeNode>();
foreach (TreeNode item in listAllTreeNodes)
{
if (item.ParentID.HasValue)
{
int parentId = item.ParentID.Value;
if (parentId == parentNode.ID)
{
List<TreeNode> ChildNodes2 = GetAllChildNodes(listAllTreeNodes, item);
item.children = ChildNodes2;
ChildNodes.Add(item);
}
}
}
return ChildNodes;
}
可以看到递归了很多次,性能不是很好。
分享到:
相关推荐
本压缩包包含有10类树叶叶片数据集,每类植物含有40张叶片图样,合计有400张树叶样本,希望为正在寻找树叶数据集进行分类等算法测试的你提供帮助
FLASH 运动引导层动画实例 飘落的树叶
Unity在URP模式下实现树叶随风飘动的Shader脚本,unity2019亲测可运行
jQuery不同树叶掉落特效代码,点击“添加更多树叶按钮”可以在顶部添加叠加更多的树叶,点击树叶会立刻掉落。
树叶素材 图片 photoshop 很好用树叶图片
树叶素材,用于Unity Shader的纹理贴图。具体使用方法见【Unity Shader】树叶晃动效果实现
基于MATLAB的树叶图像特征分类识别,图像分析处理 分割 特征提取 分类识别等
19蓝色的树叶_(第二课时).ppt
jQuery制作树叶空中飘落特效,随机生成树叶,点击树叶就飘落,在空中再点击树叶,也便多片树叶飘落。
免费资源 jQuery树叶掉落特效
YOLOv3树叶识别实践
资源名:基于matlab的树叶图像特征分类识别程序源码_树叶识别_图像识别处理_特征识别_matlab 资源类型:matlab项目全套源码 源码说明: 全部项目源码都是经过测试校正后百分百成功运行的,如果您下载后不能运行可...
Photoshop画笔笔刷树叶.tpl
AutumnLeaves绿色汉化版桌面树叶飘飘.rar 这是一款桌面软件,
资源名:树叶图像特征分类识别程序_树叶分类_图像识别_matlab 资源类型:matlab项目全套源码 源码说明: 全部项目源码都是经过测试校正后百分百成功运行的,如果您下载后不能运行可联系我进行指导或者更换。 适合...
Word模板-树叶信纸.docx
kaggle网站深度学习竞赛资源:树叶分类竞赛数据集
树叶模拟bp网络和稀疏表示算法用到的数据集,前十种是树叶的形状特征,后六种是树叶的纹理特征
七彩树叶PPT模板适用于儿童活动设计应用。