计算一棵树的深度和宽度[Treeview的深度和宽度](多题头的表格问题解决的基础)
当我有一棵树,我想知道它的枝叶最深的级别是多少?它有多少个叶子(最终的节点,我称它为宽度)?
用.net怎么来作呢?
这个题目的提出是由于要设计一个多题头的表格而抽象出来的。
动态生成一个多题头的表格如下:
由如下xml描述
完成动态的创建多题头的表格的难点在于,
一棵树的深度和宽读,一个叶枝的级别以及这个叶枝有多少个子叶枝(宽度).
=============================================================
现在我完成一些基本的东西。
先计算一个树的宽度[由此可得到一个节点的宽度的算法]
定义初始宽度
private int _treeWidth = 0 ;
利用递归算法来遍历父节点下面的所有的节点,发现是叶子的则加一
#region 计算树的宽度
/// <summary>
/// 遍历所有节点。
/// 发现节点是树叶则加一
/// 否则,取节点的子节点循环
/// </summary>
/// <param name="node"></param>
private void CountTreeWidth(TreeNode node)
{
if(node.Nodes.Count==0)
this._treeWidth ++;
else
{
for(int i=0;i<node.Nodes.Count;i++)
{
CountTreeWidth(node.Nodes[i]);
}
}
}
#endregion
计算树的深度算法我开始想了一个,结果发现有一点问题:
还是先定义初始变量,一个为最大的值,一个为目前的深度值
private int _max = 0;
private int _level =0;
第一个算法:
基本想法是,遍历所有的节点,如果节点还有子节点则加1,
否则目前深度值置为零。
#region 算法一
private void CountLevel(TreeNode MyNode)
{
_level++;
if(_level>_max)
_max = _level;
System.Diagnostics.Debug.WriteLine(MyNode.Text);
if(MyNode.Nodes.Count!=0)
{
for(int i=0;i<MyNode.Nodes.Count;i++)
{
System.Diagnostics.Debug.WriteLine(_level);
CountLevel(MyNode.Nodes[i]);
}
}
else
{
System.Diagnostics.Debug.WriteLine(_level);
//_level --;
_level = 0;
}
}
#endregion
这个算法对单根线的计算是没有问题的,
但是对于多个子节点的计算是有问题的:
看看图
为了降低解释问题的负责度,我只取这个图树的一个节点来分析。
假如我们的这个树是上图节点1开始(包括节点1下面所有子节点)。
我们看算法是怎么算的。。。
算法遍历的过程是
节点1->节点2->节点3->节点13
此时最大深度_max=4
而_level = 0[因为节点13是叶子]
继续。。
这时递归退回到节点2
节点2->节点4
_level = 1
这个时候已经出现问题,
因为节点2的level是3
而计算出来节点4的深度应该是
_level = 3
计算节点4的深度不应该重新计数
如上图如果按照算法,
节点4的
_level = 1
最后算出来的_max = 5
而真实的值应该为6
现在把算法二改进版
#region 算法二改进
/// <summary>
/// 算法还可以改进
/// 如果知道parent的级别,则本级别则等于parent的level+1
/// </summary>
/// <param name="MyNode"></param>
private void CountLevel3(TreeNode MyNode)
{
_level = 1;
if(MyNode.Parent!=null)
{
MyNode.Tag = (int)MyNode.Parent.Tag + 1;
_level = (int)MyNode.Tag;
}
//getMaxDeep(MyNode);
if(_level>_max)
_max = _level;
for(int i=0;i<MyNode.Nodes.Count;i++)
{
CountLevel3(MyNode.Nodes[i]);
}
}
#endregion
这个算法的想法是确定每个节点的级别,最顶上的是一,
节点向下遍历的时候,子节点的级别为parent level+1,
最大的付给_max,这样就可以得到树的深度了。
用.net怎么来作呢?
这个题目的提出是由于要设计一个多题头的表格而抽象出来的。
动态生成一个多题头的表格如下:

由如下xml描述
1
<item HeaderText="Lifecycle Status (Start Date)" >
2
<item HeaderText="Sample" TitleCss="trTitle2">
3
<item HeaderText="α" ColumnName="sample" TitleCss="trTitle2" Format="d" />
4
<item HeaderText="β" ColumnName="Sampleb" TitleCss="trTitle2" Format="d" />
5
<item HeaderText="ES" ColumnName="SampleES" TitleCss="trTitle2" Format="d" />
6
</item>
7
<item HeaderText="NPI" ColumnName="NPI" TitleCss="trTitle2" Format="d" />
8
<item HeaderText="CEM" ColumnName="CEM" TitleCss="trTitle2" Format="d" />
9
10
</item>
11
<item HeaderText="Under developing and technically immature" >
12
<item HeaderText="Start Date" Width="120" ColumnName="red" TitleCss="trTitle2" Format="d" />
13
<item HeaderText="Sample Available" Width="120" ColumnName="redsample" TitleCss="trTitle2" Format="d" />
14
</item>

2

3

4

5

6

7

8

9

10

11

12

13

14

完成动态的创建多题头的表格的难点在于,
一棵树的深度和宽读,一个叶枝的级别以及这个叶枝有多少个子叶枝(宽度).
=============================================================
现在我完成一些基本的东西。

先计算一个树的宽度[由此可得到一个节点的宽度的算法]
定义初始宽度

利用递归算法来遍历父节点下面的所有的节点,发现是叶子的则加一





















计算树的深度算法我开始想了一个,结果发现有一点问题:
还是先定义初始变量,一个为最大的值,一个为目前的深度值


第一个算法:
基本想法是,遍历所有的节点,如果节点还有子节点则加1,
否则目前深度值置为零。































这个算法对单根线的计算是没有问题的,
但是对于多个子节点的计算是有问题的:
看看图

为了降低解释问题的负责度,我只取这个图树的一个节点来分析。
假如我们的这个树是上图节点1开始(包括节点1下面所有子节点)。
我们看算法是怎么算的。。。
算法遍历的过程是
节点1->节点2->节点3->节点13
此时最大深度_max=4
而_level = 0[因为节点13是叶子]
继续。。
这时递归退回到节点2
节点2->节点4
_level = 1
这个时候已经出现问题,
因为节点2的level是3
而计算出来节点4的深度应该是
_level = 3
计算节点4的深度不应该重新计数

如上图如果按照算法,
节点4的
_level = 1
最后算出来的_max = 5
而真实的值应该为6
现在把算法二改进版





























这个算法的想法是确定每个节点的级别,最顶上的是一,
节点向下遍历的时候,子节点的级别为parent level+1,
最大的付给_max,这样就可以得到树的深度了。
分类:
控件使用和开发
, ASP.Net相关使用心得
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述