fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5.  
  6. namespace ConsoleApp1
  7. {
  8. class Program
  9. {
  10. static void Main(string[] args)
  11. {
  12. Console.WriteLine("Hello World!");
  13.  
  14. var items = new[]
  15. {
  16. new Item{ Parent = null, Child = "A", Name = "Alpha" },
  17. new Item{ Parent = "A", Child = "B", Name = "Bravo" },
  18. new Item{ Parent = "A", Child = "C", Name = "Charlie" },
  19. new Item{ Parent = "B", Child = "E", Name = "Echo" },
  20. new Item{ Parent = "B", Child = "F", Name = "Foxtrot" },
  21. new Item{ Parent = "C", Child = "W", Name = "Whisky" },
  22. new Item{ Parent = "C", Child = "H", Name = "Hotel" },
  23. new Item{ Parent = "W", Child = "V", Name = "Victor" },
  24. };
  25. var root = new TreeNode<Item>(items.Single(i => i.Parent == null));
  26. AddDescendants(items, root);
  27. Console.WriteLine("# Tree flat-style:");
  28. root.Traverse(item => Console.WriteLine("Node name: " + item.Value.Name));
  29.  
  30. Console.WriteLine();
  31. Console.WriteLine("# Tree indent-style:");
  32. root.Traverse(node =>
  33. {
  34. var depth = 0;
  35. var ancestor = node.Parent;
  36. while (ancestor != null)
  37. {
  38. depth++;
  39. ancestor = ancestor.Parent;
  40. }
  41. Console.WriteLine(new string(' ', depth * 2) + node.Value.Name);
  42. });
  43. Console.ReadKey();
  44. }
  45. private static void AddDescendants(IReadOnlyCollection<Item> items, TreeNode<Item> node)
  46. {
  47. var children = node.AddChildren(items.Where(i => i.Parent == node.Value.Child).ToArray());
  48. foreach (var child in children)
  49. {
  50. AddDescendants(items, child);
  51. }
  52. }
  53. }
  54.  
  55. public class Item
  56. {
  57. public string Parent { get; set; }
  58. public string Child { get; set; }
  59. public string Name { get; set; }
  60. public int Quantity { get; set; }
  61. }
  62.  
  63. public class TreeNode<T>
  64. {
  65. private readonly T _value;
  66. private readonly List<TreeNode<T>> _children = new List<TreeNode<T>>();
  67.  
  68. public TreeNode(T value)
  69. {
  70. _value = value;
  71. }
  72.  
  73. public TreeNode<T> this[int i]
  74. {
  75. get { return _children[i]; }
  76. }
  77.  
  78. public TreeNode<T> Parent { get; private set; }
  79.  
  80. public T Value { get { return _value; } }
  81.  
  82. public ReadOnlyCollection<TreeNode<T>> Children
  83. {
  84. get { return _children.AsReadOnly(); }
  85. }
  86.  
  87. public TreeNode<T> AddChild(T value)
  88. {
  89. var node = new TreeNode<T>(value) { Parent = this };
  90. _children.Add(node);
  91. return node;
  92. }
  93.  
  94. public TreeNode<T>[] AddChildren(params T[] values)
  95. {
  96. return values.Select(AddChild).ToArray();
  97. }
  98.  
  99. public bool RemoveChild(TreeNode<T> node)
  100. {
  101. return _children.Remove(node);
  102. }
  103.  
  104. public void Traverse(Action<TreeNode<T>> action)
  105. {
  106. action(this);
  107. foreach (var child in _children)
  108. child.Traverse(action);
  109. }
  110.  
  111. public IEnumerable<T> Flatten()
  112. {
  113. return new[] { Value }.Concat(_children.SelectMany(x => x.Flatten()));
  114. }
  115. }
  116. }
  117.  
Success #stdin #stdout 0.03s 15852KB
stdin
Standard input is empty
stdout
Hello World!
# Tree flat-style:
Node name: Alpha
Node name: Bravo
Node name: Echo
Node name: Foxtrot
Node name: Charlie
Node name: Whisky
Node name: Victor
Node name: Hotel

# Tree indent-style:
Alpha
  Bravo
    Echo
    Foxtrot
  Charlie
    Whisky
      Victor
    Hotel