C# 一个自己写的树结构代码(1)
2016-10-20 10:22
411 查看
这段树结构代码已经写了三四年。写的过程中经过反复修改,目前在自己的程序中以及比较成熟,在.net4下运行,有需要的人可以拿去。
主要面对字符串保存处理的问题,节点中考虑到扩展性也加入了object对象属性。节点本身使用了大量的字符串。
这篇文章里是底层的树节点以及相关调用代码。这个类是两三年之前在网上找到扩展的,对原作者表示感谢,现在搜了下找不到源了。
树节点代码:
树节点调用的链表类
主要面对字符串保存处理的问题,节点中考虑到扩展性也加入了object对象属性。节点本身使用了大量的字符串。
这篇文章里是底层的树节点以及相关调用代码。这个类是两三年之前在网上找到扩展的,对原作者表示感谢,现在搜了下找不到源了。
树节点代码:
public class MultTreeNode { #region members private int parentId; private int selfId; protected String nodeName; protected Object obj; protected MultTreeNode parentNode; protected List<MultTreeNode> childList; #endregion members #region contrustion public MultTreeNode() { init(); } public MultTreeNode(MultTreeNode parentNode) { init(parentNode); } public void init(MultTreeNode pNode = null) { if (childList == null) childList = new List<MultTreeNode>(); parentId = 0; selfId = 0; nodeName = ""; obj = null; if (pNode != null) { nodeName = pNode.getNodeName(); if (pNode.getObj() != null) obj = new Hashtable((Hashtable)pNode.getObj()); parentNode = pNode.getParentNode(); if (pNode.getChildList() != null) childList = new List<MultTreeNode>(pNode.getChildList()); } } #endregion contrustion #region check node public bool isLeaf() { return childList == null || childList.Count == 0; } public bool isRoot() { return parentNode == null; } /// <summary> /// check exist of child node. /// </summary> /// <param name="name"></param> /// <returns></returns> public bool ExistChildNode(string name)//,bool IgnoreCase = false { bool bRet = false; foreach (MultTreeNode node in childList) { if (node.nodeName == name) { bRet = true; break; } } return bRet; } #endregion check node #region insert /// <summary> /// insert child node to one node(this). /// </summary> /// <param name="name">new child node name.</param> /// <param name="path"></param> /// <param name="newnode">can be null. no use I think.</param> /// <returns></returns> virtual public MultTreeNode InsertNode(string name, string path = "", MultTreeNode newnode = null) { MultTreeNode pntnode = this; if (newnode == null) newnode = new MultTreeNode(); if (path.Length > 0) { pntnode = findNodeByPath(path); } if (pntnode == null) return null; // check if has same node with same name. // can not insert two same name node under one parent node. // 2016-03-04 09:38:33 if (pntnode.ExistChildNode(name)) return pntnode; newnode.setNodeName(name); newnode.parentNode = pntnode; pntnode.InsertChildNode(newnode); return newnode; } /** 插入一个child节点到当前节点中 */ virtual public void InsertChildNode(MultTreeNode treeNode) { if (childList == null) childList = new List<MultTreeNode>(); treeNode.setParentNode(this); childList.Add(treeNode); } #endregion insert #region get /// <summary> /// get current node 's brother node count. /// = parent node 's childlist size. /// </summary> /// <returns>current node 's brother node count</returns> public int GetBrotherNodeCount() { if (parentNode != null) { return parentNode.getChildList() != null ? parentNode.getChildList().Count : 1; } else { return 1; } } /// <summary> /// get current node 's childlist count. /// </summary> /// <returns></returns> public int GetChildNodeCount() { return childList == null ? 0 : childList.Count; } /** 找到一颗树中某个节点 按节点ID */ public MultTreeNode findNodeById(int id) { if (this.selfId == id) return this; if (isLeaf()) { return null; } else { int childNumber = childList.Count; for (int i = 0; i < childNumber; i++) { MultTreeNode child = childList.ElementAt(i); MultTreeNode resultNode = child.findNodeById(id); if (resultNode != null) { return resultNode; } } return null; } } /// <summary> /// find one note in tree. /// 2016-03-04 16:21:34 /// modify when empty path .return this instead of null. /// </summary> /// <param name="path"></param> /// <returns></returns> public MultTreeNode findNodeByPath(string path) { if (string.IsNullOrEmpty(path)) return this; path = StrUtils.FormatPath(path); path = StrUtils.GetSDirString(path); string[] pathArr = StrUtils.Split(path, "\\");//path.Split('\\'); if (pathArr[0] == null) pathArr[0] = path; // make sure this is root path. if (nodeName != pathArr[0]) return null; MultTreeNode node = this; for (int i = 0; i < pathArr.Count(); i++) { // 说明:注释。不知道为什么要加这句 可能会影响代码生成。需要注意 // 修改为 break; => continue; \ 查找具有 相同节点名称的 子节点 逻辑 // 短暂测试是正常的。 // 修改日期:2014-8-5 14:20:28 if (string.IsNullOrEmpty(pathArr[i])) { List<MultTreeNode> list = node.getChildList(); if (i < pathArr.Count() - 1) for (int j = 0; j < list.Count; j++) { if (list[j].getNodeName() == pathArr[i + 1]) { node = list[j]; } } continue; } // use path to avoid error like 0\0\0 // 2016-07-11 21:34:54 string nodePath = node.getPath(); string testPath = StrUtils.FromArr(ArrayUtils.SplitArray<string>(pathArr, 0, i - 1), "\\"); if (node.getNodeName() == pathArr[i] && nodePath == testPath) { List<MultTreeNode> list = node.getChildList(); for (int j = 0; j < list.Count; j++) { if (i + 1 < pathArr.Length && list[j].getNodeName() == pathArr[i + 1]) { node = list[j]; } } } else { node = null; break; } } return node; } /// <summary> /// build one path by node name /// </summary> /// <returns>path like directory</returns> public string getPath() { List<MultTreeNode> list = getElders(); string path = ""; for (int i = 0; i < list.Count; i++) { if (list[i] != null) { if (path.Length > 0) path += "\\"; path += list[i].getNodeName(); } } return path; } /** 返回当前节点的父辈节点集合 形成路径使用 */ public List<MultTreeNode> getElders() { ListExtA<MultTreeNode> elderList = new ListExtA<MultTreeNode>(); MultTreeNode parentNode = this.getParentNode(); if (parentNode == null) { return elderList; } else { elderList.AddAll(parentNode.getElders()); elderList.Add(parentNode); return elderList; } } /** 返回当前节点的晚辈集合 */ public List<MultTreeNode> getJuniors() { ListExtA<MultTreeNode> juniorList = new ListExtA<MultTreeNode>(); List<MultTreeNode> childList = this.getChildList(); if (childList == null) { return juniorList; } else { int childNumber = childList.Count; for (int i = 0; i < childNumber; i++) { MultTreeNode junior = childList.ElementAt(i); juniorList.Add(junior); juniorList.AddAll(junior.getJuniors()); } return juniorList; } } /** 返回当前节点的孩子集合 */ public List<MultTreeNode> getChildList() { return childList; } #endregion get #region delete /** 删除节点和它下面的晚辈 */ public void deleteNode() { MultTreeNode parentNode = this.getParentNode(); int id = this.getSelfId(); if (parentNode != null) { parentNode.deleteChildNode(id); } } /** 删除当前节点的某个子节点 * childId=0时删除所有子节点 */ public void deleteChildNode(int childId = 0) { List<MultTreeNode> childList = this.getChildList(); int childNumber = childList.Count; for (int i = 0; i < childNumber; i++) { MultTreeNode child = childList.ElementAt(i); if (child.getSelfId() == childId || childId == 0) { childList.RemoveAt(i); return; } } } #endregion delete #region loop public delegate int OneStepTravers(MultTreeNode node); /** 遍历一棵树,深度遍历 */ public void depthtraverse(OneStepTravers stepbef, OneStepTravers stepafter) { if (stepbef != null) stepbef(this); if (childList != null) { int childNumber = childList.Count; for (int i = 0; i < childNumber; i++) { MultTreeNode child = childList.ElementAt(i); child.depthtraverse(stepbef, stepafter); } } if (stepafter != null) stepafter(this); } #endregion loop #region node test public void print(String content) { System.Diagnostics.Debug.WriteLine(content); } public void print(int content) { System.Diagnostics.Debug.WriteLine(content.ToString()); } #endregion node test #region attribute public void setChildList(List<MultTreeNode> childList) { this.childList = childList; } public int getParentId() { return parentId; } public void setParentId(int parentId) { this.parentId = parentId; } public int getSelfId() { return selfId; } public void setSelfId(int selfId) { this.selfId = selfId; } public MultTreeNode getParentNode() { return parentNode; } public void setParentNode(MultTreeNode parentNode) { this.parentNode = parentNode; } public String getNodeName() { return nodeName; } public void setNodeName(String nodeName) { this.nodeName = nodeName; } public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; } #endregion attribute }后面再贴其他几个调用类,主要是几个调用函数类,字符串处理等。
树节点调用的链表类
public class ListExtA<T> : System.Collections.Generic.List<T> { public void AddAll(List<T> addlist) { for (int i = 0; i < addlist.Count; i++) Add(addlist.ElementAt(i)); } public static T Get(List<T> list, int nIndex = 0) { if (nIndex >= list.Count || nIndex < 0) return default(T); return list.ElementAt(nIndex); } }
相关文章推荐
- C# 一个自己写的树结构代码(2)-Array,HashTable,List,String数据结构操作封装
- [c#]一步一步开发自己的自动代码生成工具之一:获取sql2005的数据库表结构
- 给大家提供一个C#2.0的网站后台文章上传与前台显示的代码!呵呵!fckeditor大家自己调哦!
- 自己动手,写一个分布式系统(附c#代码示例)
- [C#]一步一步开发自己的自动代码生成工具之一:获取SQL2005的数据库表结构
- C#编写一个自己输入内容的代码
- 用Pytohn写了一个根据表结构自动生成C#对像代码的小工具
- 为自己的C# ORM 写一个代码自动生成器
- 一个动态编译并运行C#或VB.NET代码的工具[翻译]
- 一个FTP客户端的C#代码(转)
- C#分析数据库结构,使用XSL模板自动生成代码
- 今天一个数据结构的代码自己想出来,开心!!
- 网络资源--一个C#的客户端代码(zz)
- 一个简单的AJAX实现,基于C#的ASP.Net,包括服务器端的程序代码
- 自己写的.Net(C#)代码自动生成器
- C#分析数据库结构,使用XSL模板自动生成代码
- 让C++代码与C#代码一起生成一个单一的Assembly
- 用C#设计一个驱动备份的程序代码
- 一个FTP客户端的C#代码
- 一个FTP客户端的C#代码