diff --git a/src/Advanced.Algorithms/DataStructures/Tree/AvlTree.cs b/src/Advanced.Algorithms/DataStructures/Tree/AvlTree.cs
index 8d1dea92..82b9546c 100644
--- a/src/Advanced.Algorithms/DataStructures/Tree/AvlTree.cs
+++ b/src/Advanced.Algorithms/DataStructures/Tree/AvlTree.cs
@@ -34,13 +34,17 @@ public AVLTree(bool enableNodeLookUp = false)
/// Enabling lookup will fasten deletion/insertion/exists operations
/// at the cost of additional space.
public AVLTree(IEnumerable sortedCollection, bool enableNodeLookUp = false)
- : this(enableNodeLookUp)
{
ValidateSortedCollection(sortedCollection);
var nodes = sortedCollection.Select(x => new AVLTreeNode(null, x)).ToArray();
Root = (AVLTreeNode)ToBST(nodes);
recomputeHeight(Root);
assignCount(Root);
+
+ if (enableNodeLookUp)
+ {
+ nodeLookUp = nodes.ToDictionary(x => x.Value, x => x as BSTNodeBase);
+ }
}
diff --git a/src/Advanced.Algorithms/DataStructures/Tree/RedBlackTree.cs b/src/Advanced.Algorithms/DataStructures/Tree/RedBlackTree.cs
index 36121b51..c7f1126b 100644
--- a/src/Advanced.Algorithms/DataStructures/Tree/RedBlackTree.cs
+++ b/src/Advanced.Algorithms/DataStructures/Tree/RedBlackTree.cs
@@ -131,7 +131,9 @@ internal bool Exists(T value)
{
if (nodeLookUp != null)
{
- return (nodeLookUp[value] as RedBlackTreeNode, Root.Position(value));
+ //since node look up is only used by Bentley-Ottmann algorithm internally
+ //and it does'nt need the position we can return defualt(int).
+ return (nodeLookUp[value] as RedBlackTreeNode, default(int));
}
var result = Root.Find(value);
@@ -831,6 +833,7 @@ public T NextHigher(T value)
return next != null ? next.Value : default(T);
}
+ ///Special (internal only) method for Bentley-Ottmann sweep line algorithm.
internal void Swap(T value1, T value2)
{
var node1 = find(value1).Item1;
diff --git a/tests/Advanced.Algorithms.Tests/DataStructures/Tree/AVLTree_Tests.cs b/tests/Advanced.Algorithms.Tests/DataStructures/Tree/AVLTree_Tests.cs
index 7cdcf106..b5f44a74 100644
--- a/tests/Advanced.Algorithms.Tests/DataStructures/Tree/AVLTree_Tests.cs
+++ b/tests/Advanced.Algorithms.Tests/DataStructures/Tree/AVLTree_Tests.cs
@@ -98,6 +98,77 @@ public void AVLTree_Accuracy_Test()
{
var nodeCount = 1000;
+ var rnd = new Random();
+ var sorted = Enumerable.Range(1, nodeCount).ToList();
+ var randomNumbers = sorted
+ .OrderBy(x => rnd.Next())
+ .ToList();
+
+ var tree = new AVLTree();
+
+ for (int i = 0; i < nodeCount; i++)
+ {
+ tree.Insert(randomNumbers[i]);
+
+ Assert.IsTrue(tree.HasItem(randomNumbers[i]));
+ Assert.IsTrue(tree.Root.IsBinarySearchTree(int.MinValue, int.MaxValue));
+ tree.Root.VerifyCount();
+
+ var actualHeight = tree.GetHeight();
+
+ //http://stackoverflow.com/questions/30769383/finding-the-minimum-and-maximum-height-in-a-avl-tree-given-a-number-of-nodes
+ var maxHeight = 1.44 * Math.Log(nodeCount + 2, 2) - 0.328;
+
+ Assert.IsTrue(actualHeight < maxHeight);
+ Assert.IsTrue(tree.Count == i + 1);
+ }
+
+ for (int i = 0; i < sorted.Count; i++)
+ {
+ Assert.AreEqual(sorted[i], tree.ElementAt(i));
+ Assert.AreEqual(i, tree.IndexOf(sorted[i]));
+ }
+
+ randomNumbers = Enumerable.Range(1, nodeCount)
+ .OrderBy(x => rnd.Next())
+ .ToList();
+
+ //IEnumerable test using linq
+ Assert.AreEqual(tree.Count, tree.Count());
+ Assert.AreEqual(tree.Count, tree.AsEnumerableDesc().Count());
+
+ for (int i = 0; i < nodeCount; i++)
+ {
+ if (rnd.NextDouble() >= 0.5)
+ {
+ tree.Delete(randomNumbers[i]);
+ }
+ else
+ {
+ var index = tree.IndexOf(randomNumbers[i]);
+ Assert.AreEqual(tree.ElementAt(index), randomNumbers[i]);
+ tree.RemoveAt(index);
+ }
+
+ Assert.IsTrue(tree.Root.IsBinarySearchTree(int.MinValue, int.MaxValue));
+ tree.Root.VerifyCount();
+
+ var actualHeight = tree.GetHeight();
+
+ //http://stackoverflow.com/questions/30769383/finding-the-minimum-and-maximum-height-in-a-avl-tree-given-a-number-of-nodes
+ var maxHeight = 1.44 * Math.Log(nodeCount + 2, 2) - 0.328;
+
+ Assert.IsTrue(actualHeight < maxHeight);
+ }
+
+ Assert.IsTrue(tree.Count == 0);
+ }
+
+ [TestMethod]
+ public void AVLTree_Accuracy_Test_With_Node_LookUp()
+ {
+ var nodeCount = 1000;
+
var rnd = new Random();
var sorted = Enumerable.Range(1, nodeCount).ToList();
var randomNumbers = sorted
@@ -165,7 +236,7 @@ public void AVLTree_Accuracy_Test()
}
[TestMethod]
- public void AVLTree_BulkInit_Test()
+ public void AVLTree_BulkInit_Test_With_Node_LookUp()
{
var nodeCount = 1000;
@@ -199,6 +270,41 @@ public void AVLTree_BulkInit_Test()
Assert.IsTrue(tree.Count == 0);
}
+ [TestMethod]
+ public void AVLTree_BulkInit_Test()
+ {
+ var nodeCount = 1000;
+
+ var rnd = new Random();
+ var randomNumbers = Enumerable.Range(1, nodeCount).ToList();
+
+ var tree = new AVLTree(randomNumbers, true);
+
+ Assert.IsTrue(tree.Root.IsBinarySearchTree(int.MinValue, int.MaxValue));
+ Assert.AreEqual(tree.Count, tree.Count());
+
+ tree.Root.VerifyCount();
+
+ for (int i = 0; i < nodeCount; i++)
+ {
+ tree.Delete(randomNumbers[i]);
+
+ tree.Root.VerifyCount();
+ Assert.IsTrue(tree.Root.IsBinarySearchTree(int.MinValue, int.MaxValue));
+
+ var actualHeight = tree.GetHeight();
+
+ //http://stackoverflow.com/questions/30769383/finding-the-minimum-and-maximum-height-in-a-avl-tree-given-a-number-of-nodes
+ var maxHeight = 1.44 * Math.Log(nodeCount + 2, 2) - 0.328;
+
+ Assert.IsTrue(actualHeight < maxHeight);
+
+ Assert.IsTrue(tree.Count == nodeCount - 1 - i);
+ }
+
+ Assert.IsTrue(tree.Count == 0);
+ }
+
[TestMethod]
public void AVLTree_Stress_Test()
{