Skip to content

Commit 525b07b

Browse files
committed
Program does not need to know anything of the Node implementatio
1 parent 500b6bf commit 525b07b

File tree

2 files changed

+201
-14
lines changed

2 files changed

+201
-14
lines changed

BinarySearchTree/BinarySearchTree/BinarySearchTree.cs

+176-10
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,121 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34

45
namespace BinarySearchTree
56
{
7+
/// <summary>
8+
/// Represents a node in a (binary) tree.
9+
/// </summary>
10+
/// <typeparam name="T">The payload of the node as generic type.</typeparam>
611
public class Node<T>
712
{
13+
/// <summary>
14+
/// The payload of the node.
15+
/// </summary>
816
public T Value { get; set; }
917

18+
/// <summary>
19+
/// An item with lower a value than the value of this node will become a LeftNode.
20+
/// </summary>
1021
public Node<T> LeftNode;
22+
/// <summary>
23+
/// An item with higher a value than the value of this node will become a RightNode.
24+
/// </summary>
1125
public Node<T> RightNode;
1226

27+
/// <summary>
28+
/// Creates a new Node.
29+
/// </summary>
30+
/// <param name="value">Payload of the new node</param>
1331
public Node(T value)
1432
{
1533
Value = value;
1634
}
1735
}
1836

19-
public class BinarySearchTree<T> where T : IComparable
37+
38+
/// <summary>
39+
/// Data structure that stores items and allows fast lookup, insertion and deletion.
40+
/// </summary>
41+
/// <typeparam name="T">The type of the trees items.</typeparam>
42+
public class BinarySearchTree<T> where T : IComparable<T>
2043
{
2144
private Node<T> _globalRoot;
22-
public Node<T> InsertNode(Node<T> root, T value)
45+
/// <summary>
46+
/// Inserts a new node in a existing tree
47+
/// </summary>
48+
/// <param name="root">The root node of the tree</param>
49+
/// <param name="value">Value to be inserted into the tree</param>
50+
/// <returns></returns>
51+
/*public Node<T> InsertNode(ref Node<T> root, T value)
2352
{
2453
if (root == null)
2554
{
2655
root = new Node<T>(value);
27-
if(_globalRoot == null)
56+
if (_globalRoot == null)
2857
_globalRoot = root;
2958
}
3059
else
60+
{
61+
if (value.CompareTo(root.Value) <= 0)
62+
{
63+
root.LeftNode = InsertNode(root.LeftNode, value);
64+
}
65+
else if (value.CompareTo(root.Value) > 0) //Items with the same value are ignored, use >= to insert them into the three
66+
{
67+
root.RightNode = InsertNode(root.RightNode, value);
68+
}
69+
}
70+
return root;
71+
}*/
72+
73+
74+
public void InsertNode(T value)
75+
{
76+
if (_globalRoot == null)
77+
{
78+
_globalRoot = new Node<T>(value);
79+
}
80+
else
81+
{
82+
InsertNode(_globalRoot, value);
83+
}
84+
}
85+
86+
private static Node<T> InsertNode(Node<T> root, T value)
87+
{
88+
if (root == null)
89+
{
90+
root = new Node<T>(value);
91+
}
92+
else
3193
{
3294
if (value.CompareTo(root.Value) <= 0)
3395
{
3496
root.LeftNode = InsertNode(root.LeftNode, value);
3597
}
36-
else if (value.CompareTo(root.Value) >= 0)
98+
else if (value.CompareTo(root.Value) > 0)//Items with the same value are ignored, use >= to insert them into the three
3799
{
38100
root.RightNode = InsertNode(root.RightNode, value);
39101
}
40102
}
41103
return root;
42104
}
43105

44-
public IEnumerable<T> PreorderTraverseTree(Node<T> root)
106+
/// <summary>
107+
/// Preorder traversal of the tree. Visites the root, then visits the left sub-tree, after that it visits the right sub-tree.
108+
/// </summary>
109+
/// <returns></returns>
110+
public IEnumerable<T> PreorderTraverseTree()
111+
{
112+
if (_globalRoot == null) yield break;
113+
114+
foreach (var node in PreorderTraverseTree(_globalRoot))
115+
yield return node;
116+
}
117+
118+
private static IEnumerable<T> PreorderTraverseTree(Node<T> root)
45119
{
46120
if (root == null) yield break;
47121
yield return root.Value;
@@ -56,7 +130,43 @@ public IEnumerable<T> PreorderTraverseTree(Node<T> root)
56130
}
57131
}
58132

59-
public void DeleteNode(ref Node<T> root, T value)
133+
/// <summary>
134+
/// Inorder traversal of the tree.
135+
/// </summary>
136+
/// <returns></returns>
137+
public IEnumerable<T> InOrderTraverseTree()
138+
{
139+
if (_globalRoot == null) yield break;
140+
141+
foreach (var node in InOrderTraverseTree(_globalRoot))
142+
yield return node;
143+
}
144+
145+
private static IEnumerable<T> InOrderTraverseTree(Node<T> root)
146+
{
147+
if (root == null) yield break;
148+
foreach (var v in InOrderTraverseTree(root.LeftNode))
149+
{
150+
yield return v;
151+
}
152+
yield return root.Value;
153+
foreach (var v in InOrderTraverseTree(root.RightNode))
154+
{
155+
yield return v;
156+
}
157+
}
158+
159+
/// <summary>
160+
/// Deletes a node from the tree.
161+
/// </summary>
162+
/// <param name="value">Value of the node which is to be deleted.</param>
163+
public void DeleteNode(T value)
164+
{
165+
if (_globalRoot == null) return;
166+
DeleteNode(ref _globalRoot, value);
167+
}
168+
169+
private void DeleteNode(ref Node<T> root, T value)
60170
{
61171
if (root == null) return;
62172
if (root.Value.Equals(value))
@@ -69,14 +179,46 @@ public void DeleteNode(ref Node<T> root, T value)
69179
}
70180
}
71181

72-
private Node<T> Delete(ref Node<T> root)
182+
/// <summary>
183+
/// Traverses the tree to find and return a Node with a certain value.
184+
/// </summary>
185+
/// <param name="value">The value to search for</param>
186+
/// <returns></returns>
187+
public T FindNode(T value)
188+
{
189+
var res = FindNode(_globalRoot, value);
190+
191+
return res.Value;
192+
}
193+
194+
private static Node<T> FindNode(Node<T> root, T value)
195+
{
196+
Node<T> res = null;
197+
if (root.LeftNode != null)
198+
res = FindNode(root.LeftNode, value);
199+
200+
if (value.CompareTo(root.Value) == 0)
201+
return root;
202+
203+
if (res == null && root.RightNode != null)
204+
res = FindNode(root.RightNode, value);
205+
206+
return res;
207+
}
208+
209+
/// <summary>
210+
/// Only use with custom implementations of DeleteNode!
211+
/// </summary>
212+
/// <param name="root">The root node of the tree.</param>
213+
/// <returns></returns>
214+
public Node<T> Delete(ref Node<T> root)
73215
{
74216
var tempValue = default(T);
75217

76-
if (_globalRoot == root)
218+
if (_globalRoot == root && root.LeftNode == null && root.RightNode == null)
77219
{
78-
//Deletion of root element is not allowed;
79-
return root;
220+
//Deletion of root element is allowed - to for forbid it, return root
221+
return null;
80222
}
81223
if (root.LeftNode == null && root.RightNode == null)
82224
{
@@ -111,5 +253,29 @@ private static void Replace(ref Node<T> root, ref T newValue)
111253
Replace(ref root.LeftNode, ref newValue);
112254
}
113255
}
256+
257+
public BinarySearchTree<T> BalancedTree()
258+
{
259+
var balanced = new BinarySearchTree<T>();
260+
var inorder = InOrderTraverseTree().ToArray();
261+
262+
balanced._globalRoot = BalanceTree(inorder, 0, inorder.Length - 1);
263+
264+
return balanced;
265+
}
266+
267+
private static Node<T> BalanceTree(IReadOnlyList<T> inorder, int startIndex, int endIndex)
268+
{
269+
if (startIndex > endIndex) return null;
270+
271+
var middIndex = (startIndex + endIndex) / 2;
272+
273+
var root = new Node<T>(inorder[middIndex]);
274+
275+
root.LeftNode = BalanceTree(inorder, startIndex, middIndex - 1);
276+
root.RightNode = BalanceTree(inorder, middIndex + 1, endIndex);
277+
278+
return root;
279+
}
114280
}
115281
}

BinarySearchTree/BinarySearchTree/Program.cs

+25-4
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,48 @@ static void Main(string[] args)
2424

2525
foreach (var r in rnd)
2626
{
27-
root = tree.InsertNode(root, r);
27+
tree.InsertNode(r);
2828
}
2929

3030
Console.WriteLine("input array: ");
3131
Console.WriteLine(string.Join(",", rnd));
3232
Console.ReadLine();
3333

34-
var values = tree.PreorderTraverseTree(root).ToList();
34+
var values = tree.PreorderTraverseTree().ToList();
3535
Console.WriteLine("the trees preorder traversal: ");
3636
Console.WriteLine(string.Join(",", values));
3737
Console.ReadLine();
3838

39+
var vals = tree.InOrderTraverseTree().ToList();
40+
Console.WriteLine("the trees inorder traversal: ");
41+
Console.WriteLine(string.Join(",", vals));
42+
Console.ReadLine();
43+
3944
var rndItem = rnd[rndNo.Next(0, rnd.Length)];
4045
Console.WriteLine(rndItem + " will be deleted from tree");
4146
Console.ReadLine();
42-
tree.DeleteNode(ref root, rndItem);
47+
tree.DeleteNode(rndItem);
4348

44-
var restTree = tree.PreorderTraverseTree(root).ToList();
49+
var restTree = tree.PreorderTraverseTree().ToList();
4550
Console.WriteLine("tree after deletion: ");
4651
Console.WriteLine(string.Join(",", restTree));
4752
Console.ReadLine();
53+
54+
var treeContent = tree.PreorderTraverseTree().ToList();
55+
var rndItem1 = treeContent[2];
56+
Console.WriteLine("try to find: " + rndItem1);
57+
var test = tree.FindNode(rndItem1);
58+
Console.WriteLine("Found: "+test);
59+
Console.ReadLine();
60+
61+
Console.WriteLine("Balancing tree now");
62+
var balancedTree = tree.BalancedTree();
63+
64+
var balancedPreOrder = balancedTree.PreorderTraverseTree().ToList();
65+
Console.WriteLine("preorder traversal of balanced tree: ");
66+
Console.WriteLine(string.Join(",", balancedPreOrder));
67+
Console.ReadLine();
68+
4869
}
4970
}
5071
}

0 commit comments

Comments
 (0)