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