C#树类型及其遍历
最近有个项目不仅需要取部门的层级关系,还要处理不规则的关系(移除某个部门),只有树结构才能实现相关遍历和操作。
涉及到的知识点:泛型、递归、数据结构
既然研究树类型就先来看下树的定义:
一棵树(tree)是由n(n>0)个元素组成的有限集合,其中:
(1)每个元素称为结点(node);
(2)有一个特定的结点,称为根结点或根(root);
(3)除根结点外,其余结点被分成m(m>=0)个互不相交的有限集合,而每个子集又都是一棵树(称为原树的子树);——百度
本文将简化树,只研究树的结点-结点树。结点树包含:父结点(根结点的父结点为null)、子结点(List集合)、数据对象。
类的设计:
public class BoTree<T>
{
public BoTree()
{
nodes = new List<BoTree<T>>();
} public BoTree(T data)
{
this.Data = data;
nodes = new List<BoTree<T>>();
} private BoTree<T> parent;
/// <summary>
/// 父结点
/// </summary>
public BoTree<T> Parent
{
get { return parent; }
}
/// <summary>
/// 结点数据
/// </summary>
public T Data { get; set; } private List<BoTree<T>> nodes;
/// <summary>
/// 子结点
/// </summary>
public List<BoTree<T>> Nodes
{
get { return nodes; }
}
/// <summary>
/// 添加结点
/// </summary>
/// <param name="node">结点</param>
public void AddNode(BoTree<T> node)
{
if (!nodes.Contains(node))
{
node.parent = this;
nodes.Add(node);
}
}
/// <summary>
/// 添加结点
/// </summary>
/// <param name="nodes">结点集合</param>
public void AddNode(List<BoTree<T>> nodes)
{
foreach (var node in nodes)
{
if (!nodes.Contains(node))
{
node.parent = this;
nodes.Add(node);
}
}
}
/// <summary>
/// 移除结点
/// </summary>
/// <param name="node"></param>
public void Remove(BoTree<T> node)
{
if (nodes.Contains(node))
nodes.Remove(node);
}
/// <summary>
/// 清空结点集合
/// </summary>
public void RemoveAll()
{
nodes.Clear();
}
}
测试:
首先创建一个学生类(任意)
public class Student
{
public Student(string name, string sex, int age)
{
this.Name = name;
this.Sex = sex;
this.Age = age;
}
public string Name { get; set; }
public string Sex { get; set; }
public int Age { get; set; }
}
初始化树:
BoTree<Student> tree1 = new BoTree<Student>();
tree1.Data = new Student("小波1", "男", ); BoTree<Student> tree2 = new BoTree<Student>();
tree2.Data = new Student("小波2", "男", ); BoTree<Student> tree3 = new BoTree<Student>();
tree3.Data = new Student("小波3", "男", ); BoTree<Student> tree4 = new BoTree<Student>();
tree4.Data = new Student("小波4", "男", ); tree1.AddNode(tree2);
tree1.AddNode(tree3);
tree3.AddNode(tree4);
调试:
可以从监视中看出tree1有2个子结点
可以看出tree4的父结点为tree3
下面我们来遍历这棵树:
public static void Recursive(BoTree<Student> tree)
{
Console.WriteLine("姓名:{0},姓名:{1},年龄:{2}", tree.Data.Name, tree.Data.Sex, tree.Data.Age);
if (tree.Nodes.Count > )
{
foreach (var item in tree.Nodes)
{
Recursive(item);
}
}
}
调用结果:
需要说明的是:不要尝试用Nodes.Add(T item)来添加结点,而是用AddNode方法来添加结点。AddNode方法将对Parent进行赋值,保证了父结点可查询
C#树类型及其遍历的更多相关文章
- 树和二叉树->遍历
文字描述 二叉树的先根遍历 若二叉树为空,则空操纵,否则 (1) 访问根结点 (2) 先根遍历左子树 (3) 先根遍历右子树 二叉树的中根遍历 若二叉树为空,则空操纵,否则 (1) 中根遍历左子树 ( ...
- 深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types
匿名函数 匿名函数(Anonymous Function)是表示“内联”方法定义的表达式.匿名函数本身及其内部没有值或者类型,但是可以转换为兼容的委托或者表达式树类型(了解详情).匿名函数转换的计算取 ...
- List Leaves 树的层序遍历
3-树2 List Leaves (25 分) Given a tree, you are supposed to list all the leaves in the order of top do ...
- 树的深度优先遍历和广度优先遍历的原理和java实现代码
import java.util.ArrayDeque; public class BinaryTree { static class TreeNode{ int value; TreeNode le ...
- Tree(树的还原以及树的dfs遍历)
紫书:P155 uva 548 You are to determine the value of the leaf node in a given binary tree that is th ...
- 多级树的深度遍历与广度遍历(Java实现)
目录 多级树的深度遍历与广度遍历 节点模型 深度优先遍历 广度优先遍历 多级树的深度遍历与广度遍历 深度优先遍历与广度优先遍历其实是属于图算法的一种,多级树可以看做是一种特殊的图,所以多级数的深/广遍 ...
- Uva 122 树的层次遍历 Trees on the level lrj白书 p149
是否可以把树上结点的编号,然后把二叉树存储在数组中呢?很遗憾如果结点在一条链上,那将是2^256个结点 所以需要采用动态结构 首先要读取结点,建立二叉树addnode()+read_input()承担 ...
- PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由
03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...
- hdu 4605 线段树与二叉树遍历
思路: 首先将所有的查询有一个vector保存起来.我们从1号点开始dfs这颗二叉树,用线段树记录到当前节点时,走左节点的有多少比要查询该节点的X值小的,有多少大的, 同样要记录走右节点的有多少比X小 ...
随机推荐
- Win7局域网内共享文件设置方式
1.右键-->打开网络和共享中心 2.打开网络和共享中心-->单击更改高级共享设置 3.选中文件(夹)-->属性->共享 4.共享-->添加用户,并赋予相应权限 5.选中 ...
- 转载关于Python Web后端开发面试心得
先介绍下我的情况:通信背景,工作一年多不到两年.之前一直在做C++的MFC软件界面开发工作.公司为某不景气的国企研究所.(喏,我的工作经验很水:1是方向不对:2是行业有偏差).然后目前是在寻找Pyth ...
- centOs6.5配置启动ssh
.非root用户则执行su或su - 或su root或su - root切换为root用户 2.查看SSH是否安装(检查是否装了SSH包) 输入命令:rpm -qa | grep ssh 注:若没安 ...
- Codeforces 677 - A/B/C/D/E - (Undone)
链接: A - Vanya and Fence - [水] AC代码: #include<bits/stdc++.h> using namespace std; ; int n,h; in ...
- 【Python全栈-后端开发】Django进阶之Model操作复习
Django进阶之Model操作复习 一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - ...
- JavaWeb & Tomcat
1 JavaWeb概述 Java在服务器端的应用有Servlet,JSP和第三方框架等. Java的Web框架基本都遵循特定的路数:使用Servlet或者Filter拦截请求,使用MVC的思想设计架构 ...
- PyQt5简介及demo
PyQt5说明 pyqt5是一套Python绑定Digia QT5应用的框架.它可用于Python 2和3.本教程使用Python 3.Qt库是最强大的GUI库之一.pyqt5的官方网站http:// ...
- Linux应用之crontab定时任务的设置
实现Linux定时任务有:cron.anacron.at等,这里主要介绍cron服务. 名词解释: cron是服务名称,crond是后台进程,crontab则是定制好的计划任务表. 软件包安装: 要使 ...
- Oracle 11g R2创建数据库之手工建库方式
在之前的博文当中梳理了关于DBCA静默方式创建数据库的过程,本文就手工通过SQL*PLUS客户端采用CREATE DATABASE语句创建数据库.这种建库方式就是完全使用手工SQL语句创建数据库,通常 ...
- gitlab的ssh key有2个
Gitlab添加SSH key可以pull不能push的问题 最后解决的是 使用http去clone pull 提交 没用ssh.就是需要输入密码