CSDN-CSDN社区-.NET技术-ASP.NET
public interface INode : System.Collections.Generic.IEnumerable { INode Parent { get;set;} //取得父结点 INodeList Childs { get; } //取得下级节点 INodeList Leafs { get;} //取得以该节点为根的子数的叶子节点 bool IsLeaf { get;} //是否为叶子结点 int Tier { get;} //取得该节点在树中的所处层数(从0开始计数) int Depth { get;} //取得以该节点为根的子数的深度(本层为0) IAttributeDictionary Attributes { get;set;} //该节点的属性集合 object Content { get;set;} //节点中的内容 #region children operation void AddChild(INode child); bool RemoveChild(INode child); void ClearChildren(); #endregion string ToString(); //将节点和其属性以及内容表示为网页可显示的字符串 } public interface ITree : INode { //ITree FullFill(); //返回该树的"满数" ITree FullFill() where T : INode, new(); //泛型版本(用类型T来填充) new string ToString(); //1循环子节点 2调用INode的[前序遍历] 3调用INode.ToString(); 4每行开始、结束(遍历到叶子节点)加上 5加上 } /// /// Node 的摘要说明 /// public abstract class BaseNode : INode { protected INode parent; //父节点 protected IList childs = new List(); //子节点的"内部表现" public BaseNode() { } public BaseNode(INode parent) { parent.AddChild(this); this.parent = parent; } //private void initial() //{ //} #region INode 成员 /// /// 取得父结点 /// public INode Parent { get { return this.parent; } set { value.AddChild(this); //设定父节点的同时,在父节点的子列表中加入该结点 this.parent = value; } } /// /// 取得下级节点--子结点的外部表现(只读) /// public INodeList Childs { get { return new BaseNodeList(childs); } } /// /// 取得以该节点为根的子数的叶子节点 /// public INodeList Leafs { get { IList leafs = new List(); foreach (INode node in this) { //判断是否为叶子结点 if (node.Childs.Count == 0) leafs.Add(node); } return new BaseNodeList(leafs); } } /// /// 是否是叶子结点 /// public bool IsLeaf { get { if (this.childs.Count == 0) return true; return false; } } /// /// 取得该节点在树中的所处层数(从0开始计数) /// public int Tier { get { return this.getTier(this); } } /// /// 取得以该节点为根的子数的深度(本层为0) /// public int Depth { get { return this.getDepth(this); } } #region 抽象方法 /// /// 属性列表(根据其ToString方法来显示) /// public abstract IAttributeDictionary Attributes { get;set;} /// /// 结点内容(可以是任何对象,最终根据INode.ToString方法来显示) /// public abstract object Content { get;set;} /// /// 必须重写ToString方法,用于呈现该INode /// /// public abstract override string ToString(); #endregion #region 操作子结点 /// /// 添加一个子结点 /// /// public void AddChild(INode item) { INode oldParent = item.Parent; //原父结点 if (oldParent == null || oldParent.RemoveChild(item)) //从原父节点的子结点中移除该结点 { childs.Add(item); //item.Parent = this; //该句会导致无限递归错误! ((BaseNode)item).parent = this; } } /// /// 移除一个子结点 /// /// /// public bool RemoveChild(INode item) { if (this.childs.Remove(item)) { item.Parent = null; return true; } return false; } /// /// 清空子结点 /// public void ClearChildren() { foreach (INode node in childs) { childs.Remove(node); } } #endregion #endregion #region IEnumerable 成员 /// /// 先序遍历 /// /// public IEnumerator GetEnumerator() { Queue queueList = new Queue(); //按序进出的队列 perOrderTraverse(queueList, this); //本身不入队列 while (queueList.Count > 0 && queueList.Peek() != null) { yield return queueList.Dequeue(); } } #endregion #region IEnumerable 成员 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion /// /// 先序遍历,并按序入队列 /// private void perOrderTraverse(Queue queueList, INode parentNode) { foreach (INode node in parentNode.Childs) { queueList.Enqueue(node); perOrderTraverse(queueList, node); } } /// /// 取得深度 /// private int getDepth(INode node) { if (node == null || node.Childs.Count == 0) return 0; int[] childDepthArray = new int[node.Childs.Count]; INodeList childList = node.Childs; for (int i = 0; i < childList.Count; i++) { childDepthArray[i] = getDepth(childList[i]); } Array.Sort(childDepthArray); //升序排序 return childDepthArray[childDepthArray.Length - 1] + 1; //取得最大层数子树的层数 + 1 } /// /// 取得层数 /// private int getTier(INode node) { int tier = 0; INode n = node; while (n.Parent != null) { n = n.Parent; tier++; } return tier; } }
/// <summary> /// Tree 的摘要说明 /// </summary> public class BaseTree : BaseNode, ITree { protected IAttributeDictionary attributes = new BaseAttributeDictionary(); //属性集合 #region ITree 成员 ///// <summary> ///// 返回该树的"满数" ///// </summary> ///// <returns></returns> //public virtual ITree FullFill() //{ // int treeHeight = this.Depth; //该树的高度 // INodeList leafs = this.Leafs; //该树的叶子集合 // foreach (INode node in leafs) // { // int tier = node.Tier; //某叶子结点的所在层数 // if (tier < treeHeight)//填到树的高度 // { // int length = treeHeight - tier; //需要填充的高度 // this.addFixLengthNode(length, node); // } // } // return this; //} /// <summary> /// 返回该树的"满数"(用T类型的结点填充) /// </summary> /// <returns></returns> public virtual ITree FullFill<T>() where T : INode, new() { int treeHeight = this.Depth; //该树的高度 INodeList leafs = this.Leafs; //该树的叶子集合 foreach (INode node in leafs) { int tier = node.Tier; //某叶子结点的所在层数 if (tier < treeHeight)//填到树的高度 { int length = treeHeight - tier; //需要填充的高度 this.addFixLengthNode<T>(length, node); } } return this; } #endregion #region IEnumerable 成员 public new IEnumerator GetEnumerator() { return base.GetEnumerator(); } #endregion public override IAttributeDictionary Attributes { get { return this.attributes; } set { this.attributes = value; } } public override object Content { get { return this.ToString(); } set { new Exception("不可更改内容"); } } /// <summary> /// 1循环子节点 /// 2调用INode的[前序遍历] /// 3调用INode.ToString(); /// 4每行开始<tr>、结束(遍历到叶子节点)加上<![CDATA[</tr> ]]> /// 5加上<![CDATA[<table></table>]]> /// </summary> /// <returns></returns> public override string ToString() { System.Text.StringBuilder builder = new System.Text.StringBuilder(); builder.Append("<table ").Append(this.attributes == null ? "" : this.attributes.ToString()).Append(">"); //加上table的属性 //多根循环 //foreach (INode rootNode in this.Childs) { builder.Append(@"<tr>"); foreach (INode node in this) //前序遍历 { //加上rowspan属性 countRowSpan(node); builder.Append(node.ToString()); if (node.IsLeaf) { builder.Append(@"</tr><tr>"); } } builder.Remove(builder.Length - 4, 4); //移除最后的<tr> } builder.Append(@"</table>"); return builder.ToString(); } /// <summary> /// 计算td的rowspan,并加上rowspan属性 /// </summary> /// <param name="node">原结点</param> protected virtual void countRowSpan(INode node) { int value = node.Leafs.Count; //计算叶子结点(rowspan的值) if (node.Attributes == null) { node.Attributes = new BaseAttributeDictionary(); } IAttri attri = new SingletonAttri("rowspan", value.ToString()); node.Attributes.Add(attri); //加上rowspan属性 } ///// <summary> ///// 填充固定长度线性树 ///// </summary> //private void addFixLengthNode(int length, INode parent) //{ // if (length < 1) // throw new Exception("无效长度,必须大于1"); // INode node = new SingletonNode(parent, " "); //空节点 // for (int i = 0; i < length - 1; i++) // { // INode tempNode = new SingletonNode(" "); //空节点 // node.AddChild(tempNode); // node = tempNode; //持有下一个节点 // } //} /// <summary> /// 填充固定长度线性树(用类型T填充) /// </summary> private void addFixLengthNode<T>(int length, INode parent) where T : INode, new() { if (length < 1) throw new Exception("无效长度,必须大于1"); INode node = new T(); //空节点 node.Parent = parent; node.Content = " "; for (int i = 0; i < length - 1; i++) { INode tempNode = new T(); //空节点 tempNode.Content = " "; node.AddChild(tempNode); node = tempNode; //持有下一个节点 } } }
/// <summary> /// SingletonNode -- 单td树结点 /// </summary> public class SingletonNode : BaseNode { private string content; //td中的内容 private IAttributeDictionary attributes = new BaseAttributeDictionary(); //td中的属性集合 #region 构造器 public SingletonNode() { } public SingletonNode(string content) { this.content = content; } public SingletonNode(INode parent, string content) : base(parent) { this.content = content; } public SingletonNode(INode parent, string content, IAttributeDictionary attributes) : this(parent, content) { this.attributes = attributes; //属性列表 } #endregion public override IAttributeDictionary Attributes { get { return this.attributes; } set { this.attributes = value; } } public override object Content { get { return this.content; } set { this.content = value.ToString(); } } public override string ToString() { System.Text.StringBuilder builder = new System.Text.StringBuilder(); string attriStr = attributes.ToString(); //属性 string showContent = this.content; if (string.IsNullOrEmpty(content)) showContent = " "; //若该td中内容为空则需要显示一个空格,否则该td会显示不出来 builder.Append(@"<td ").Append(attriStr).Append(@">").Append(showContent).Append(@"</td>"); return builder.ToString(); } }
/// <summary> /// ContainIndexNode 包含index的结点 /// </summary> public class ContainIndexNode : BaseNode { private string content; //td2中的内容 private IAttributeDictionary attributes = new BaseAttributeDictionary(); //td中的属性集合 #region 构造器 public ContainIndexNode() { } public ContainIndexNode(string content) { this.content = content; } public ContainIndexNode(INode parent, string content) : base(parent) { this.content = content; } public ContainIndexNode(INode parent, string content, IAttributeDictionary attributes) : this(parent, content) { this.attributes = attributes; //属性列表 } #endregion public override IAttributeDictionary Attributes { get { return this.attributes; } set { this.attributes = value; } } public override object Content { get { return this.content; } set { this.content = value.ToString(); } } public override string ToString() { System.Text.StringBuilder builder = new System.Text.StringBuilder(); string attriStr = attributes.ToString(); //属性 string showContent = this.content; if (string.IsNullOrEmpty(content)) showContent = " "; //若该td中内容为空则需要显示一个空格,否则该td会显示不出来 builder.Append(@"<td ").Append(attriStr).Append(@">").Append(this.getIndex()).Append(@"</td>"); builder.Append(@"<td ").Append(attriStr).Append(@">").Append(showContent).Append(@"</td>"); return builder.ToString(); } #region 取得索引 private string getIndex() { System.Text.StringBuilder builder = new System.Text.StringBuilder(); System.Collections.Generic.Stack<int> stack = new System.Collections.Generic.Stack<int>(); int parts = this.Tier; int index = 0; INode node = this; while (index < parts) { int num = this.getIndex(node); stack.Push(num); node = node.Parent; index++; } while (stack.Count > 0) { builder.Append(stack.Pop()).Append("."); } builder.Remove(builder.Length - 1, 1); //移除最后的点 return builder.ToString(); } private int getIndex(INode node) { INodeList list = node.Parent.Childs; for (int i = 0; i < list.Count; i++) { if (list[i] == node) return i + 1; } return 0; } #endregion }
该回复于2008-05-27 18:04:54被版主删除
得分回复需要阅读,请登录CSDN!
3
2