Skip to content

Commit 7ae23a1

Browse files
ClémentClément
authored andcommitted
Added code to remove values from AVLTrees.
1 parent ecaa473 commit 7ae23a1

2 files changed

Lines changed: 90 additions & 2 deletions

File tree

source/code/projects/AVLTree/AVLTree/AVLTree.cs

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,22 @@ public void Clear()
4646
{
4747
root = null;
4848
}
49+
50+
public T FindMin()
51+
{
52+
if (root == null)
53+
throw new ApplicationException("FindMin called on empty BinSearchTree");
54+
else
55+
return FindMin(root);
56+
}
57+
private T FindMin(Node nodeP)
58+
{
59+
if (nodeP.left == null)
60+
return nodeP.Data;
61+
else
62+
return FindMin(nodeP.left);
63+
}
64+
4965
private int GetHeight(Node nodeP)
5066
{
5167
if (nodeP == null)
@@ -68,13 +84,17 @@ private int UpdateHeight(Node nodeP)
6884
return height;
6985
}
7086

71-
//
7287
private int SubtreeBalance(Node nodeP)
7388
{
7489
// Will return
7590
// a negative number if subtree is right-heavy
7691
// a positive number if subtree is left-heavy
7792
// 0 if the subtree is perfectly balanced.
93+
// The AVL tree will need to be re-balanced if the value
94+
// returned is greater than or equal to 2, or
95+
// less than or equal to -2.
96+
// Stated differently, if the value returned is
97+
// -1, 0 or 1, then no re-balancing will take place.
7898
UpdateHeight(nodeP.left);
7999
UpdateHeight(nodeP.right);
80100
int balance;
@@ -88,7 +108,7 @@ private int SubtreeBalance(Node nodeP)
88108
}
89109
else if (nodeP.left == null)
90110
{
91-
balance = -(nodeP.right.Height + 1); // right side heavy represented by negative number
111+
balance = -(nodeP.right.Height + 1);
92112
}
93113
else if (nodeP.right == null)
94114
{
@@ -294,6 +314,70 @@ private int Depth(Node nodeP, int depth)
294314
return result;
295315
}
296316

317+
public bool Remove(T value)
318+
{
319+
return Remove(value, ref root);
320+
}
321+
322+
private bool Remove(T value, ref Node nodeP)
323+
{
324+
bool found = false;
325+
if (nodeP != null)
326+
{
327+
if (value.CompareTo(nodeP.Data) < 0) // value < nodeP.Data, check left subtree
328+
{
329+
found = Remove(value, ref nodeP.left); // similar to BST's find and remove method
330+
if (SubtreeBalance(nodeP) <= -2) // negative balance means heavy on right side
331+
{
332+
if (SubtreeBalance(nodeP.right) <= 0) // children in straight line
333+
nodeP = RotaterightChild(nodeP); // rotate middle up to balance
334+
else
335+
nodeP = DoublerightChild(nodeP); // children in zig patter - needs double rotate to balance
336+
}
337+
}
338+
else if (value.CompareTo(nodeP.Data) > 0) // value > nodeP.Data, check right subtree
339+
{
340+
found = Remove(value, ref nodeP.right);
341+
if (SubtreeBalance(nodeP) >= 2)
342+
{
343+
if (SubtreeBalance(nodeP.left) >= 0)
344+
nodeP = RotateleftChild(nodeP);
345+
else
346+
nodeP = DoubleleftChild(nodeP);
347+
}
348+
}
349+
else // The value was found!
350+
{
351+
found = true;
352+
if (nodeP.left != null && nodeP.right != null) // Two children
353+
{
354+
nodeP.Data = FindMin(nodeP.right);
355+
Remove(nodeP.Data, ref nodeP.right);
356+
if (SubtreeBalance(nodeP) == 2) // Need to rebalance
357+
{
358+
if (SubtreeBalance(nodeP.left) >= 0)
359+
nodeP = RotateleftChild(nodeP);
360+
else
361+
nodeP = DoubleleftChild(nodeP);
362+
}
363+
364+
}
365+
else
366+
{
367+
nodeP = nodeP.left ?? nodeP.right; // replace with one or no child
368+
// This is equivalent to
369+
// if (nodeP.left == null){
370+
// nodeP = nodeP.right;
371+
// } else { nodeP = nodeP.left;}
372+
// Observe that if both are null, then nodeP simply
373+
// becomes null, as expected.
374+
}
375+
}
376+
}
377+
return found;
378+
}
379+
380+
297381
// The ToString method is simply here to help us debug.
298382
// It is not really pretty, but using pre-order and spaces
299383
// to make it easier to understand how the tree is

source/code/projects/AVLTree/AVLTree/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@ static void Main()
1212
}
1313
Console.WriteLine(test);
1414

15+
Console.WriteLine("Is 7 in tree: " + test.Remove(7));
16+
Console.WriteLine("Is 7 in tree: " + test.Remove(7));
17+
Console.WriteLine(test);
18+
1519
}
1620
}

0 commit comments

Comments
 (0)