PageRenderTime 32ms CodeModel.GetById 26ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/Utilities/Collections/TreeNode.cs

#
C# | 225 lines | 142 code | 15 blank | 68 comment | 12 complexity | a29d61f67523da6b7615b67ddf51eb81 MD5 | raw file
  1using System.Collections.Generic;
  2
  3namespace Delta.Utilities.Collections
  4{
  5	/// <summary>
  6	/// Tree node class for tree node collections.
  7	/// </summary>
  8	public class TreeNode<T>
  9	{
 10		#region Parent (Public)
 11		/// <summary>
 12		/// Parent node
 13		/// </summary>
 14		/// <typeparam name="T">T</typeparam>
 15		/// <returns>Tree node</returns>
 16		public TreeNode<T> Parent
 17		{
 18			get
 19			{
 20				return mParent;
 21			}
 22			internal set
 23			{
 24				mParent = value;
 25			}
 26		}
 27		#endregion
 28
 29		#region Children (Public)
 30		/// <summary>
 31		/// Node collection of children
 32		/// </summary>
 33		/// <typeparam name="T">T</typeparam>
 34		/// <returns>Node collection</returns>
 35		public TreeNodeCollection<T> Children
 36		{
 37			get
 38			{
 39				return mChildren;
 40			}
 41		}
 42		#endregion
 43
 44		#region Root (Public)
 45		/// <summary>
 46		/// Root node
 47		/// </summary>
 48		/// <typeparam name="T">T</typeparam>
 49		/// <returns>Node</returns>
 50		public TreeNode<T> Root
 51		{
 52			get
 53			{
 54				if (null == mParent)
 55				{
 56					return this;
 57				}
 58				return mParent.Root;
 59			}
 60		}
 61		#endregion
 62
 63		#region Data (Public)
 64		/// <summary>
 65		/// Data
 66		/// </summary>
 67		/// <typeparam name="T">T</typeparam>
 68		/// <returns>Element</returns>
 69		public T Data
 70		{
 71			get
 72			{
 73				return mData;
 74			}
 75		}
 76		#endregion
 77
 78		#region Private
 79
 80		#region mChildren (Private)
 81		/// <summary>
 82		/// M children
 83		/// </summary>
 84		/// <typeparam name="T">T</typeparam>
 85		private readonly TreeNodeCollection<T> mChildren;
 86		#endregion
 87
 88		#region mData (Private)
 89		/// <summary>
 90		/// M data
 91		/// </summary>
 92		/// <returns>T</returns>
 93		/// <typeparam name="T">T</typeparam>
 94		private readonly T mData;
 95		#endregion
 96
 97		#region mParent (Private)
 98		/// <summary>
 99		/// M parent
100		/// </summary>
101		/// <typeparam name="T">T</typeparam>
102		private TreeNode<T> mParent;
103		#endregion
104
105		#endregion
106
107		#region Constructors
108		/// <summary>
109		/// Create tree node
110		/// </summary>
111		/// <param name="nodedata">Nodedata</param>
112		public TreeNode(T nodedata)
113		{
114			mChildren = new TreeNodeCollection<T>(this);
115			mData = nodedata;
116		}
117		#endregion
118
119		#region IsAncestorOf (Public)
120		/// <summary>
121		/// Is this node an ancestor of the given rhs node.
122		/// </summary>
123		/// <param name="rhs">Tree node to check</param>
124		/// <returns>
125		/// True if the given node is an ancestor (directly or recursively).
126		/// </returns>
127		public bool IsAncestorOf(TreeNode<T> rhs)
128		{
129			if (mChildren.Contains(rhs))
130			{
131				return true;
132			}
133			foreach (TreeNode<T> kid in mChildren)
134			{
135				if (kid.IsAncestorOf(rhs))
136				{
137					return true;
138				}
139			}
140			return false;
141		}
142		#endregion
143
144		#region IsDescendantOf (Public)
145		/// <summary>
146		/// Is this node a descendant of the given tree node.
147		/// </summary>
148		/// <param name="rhs">Tree node to check</param>
149		/// <returns>True if we are a descendant of rhs, false otherwise.</returns>
150		public bool IsDescendantOf(TreeNode<T> rhs)
151		{
152			if (null == mParent)
153			{
154				return false;
155			}
156			if (rhs == mParent)
157			{
158				return true;
159			}
160			return mParent.IsDescendantOf(rhs);
161		}
162		#endregion
163
164		#region DoesShareHierarchyWith (Public)
165		/// <summary>
166		/// Does share hierarchy with
167		/// </summary>
168		/// <param name="rhs">rhs</param>
169		/// <returns>
170		/// True if we share hierarchy (we are either a parent or child of the
171		/// given rhs node). False otherwise (disconnected trees).
172		/// </returns>
173		public bool DoesShareHierarchyWith(TreeNode<T> rhs)
174		{
175			if (rhs == this ||
176			    IsAncestorOf(rhs) ||
177			    IsDescendantOf(rhs))
178			{
179				return true;
180			}
181			return false;
182		}
183		#endregion
184
185		#region GetDepthFirstEnumerator (Public)
186		/// <summary>
187		/// GetDepthFirstEnumerator
188		/// </summary>
189		/// <returns>IEnumerator</returns>
190		public IEnumerator<T> GetDepthFirstEnumerator()
191		{
192			yield return mData;
193			foreach (TreeNode<T> kid in mChildren)
194			{
195				IEnumerator<T> kidenumerator = kid.GetDepthFirstEnumerator();
196				while (kidenumerator.MoveNext())
197				{
198					yield return kidenumerator.Current;
199				}
200			}
201		}
202		#endregion
203
204		#region GetBreadthFirstEnumerator (Public)
205		/// <summary>
206		/// GetBreadthFirstEnumerator
207		/// </summary>
208		/// <returns>IEnumerator</returns>
209		public IEnumerator<T> GetBreadthFirstEnumerator()
210		{
211			Queue<TreeNode<T>> todo = new Queue<TreeNode<T>>();
212			todo.Enqueue(this);
213			while (0 < todo.Count)
214			{
215				TreeNode<T> n = todo.Dequeue();
216				foreach (TreeNode<T> kid in n.mChildren)
217				{
218					todo.Enqueue(kid);
219				}
220				yield return n.mData;
221			}
222		}
223		#endregion
224	}
225}