Skip to content

Commit 37aa18c

Browse files
ClémentClément
authored andcommitted
Explaning other iteration of AVLtree.
1 parent f4aa555 commit 37aa18c

5 files changed

Lines changed: 224 additions & 13 deletions

File tree

source/code/projects/AVLTree_I/AVLTree/BSTree.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33

4-
public class BSTree<T> : BTree<T>
4+
public class BSTree<T> : IBTree<T>
55
where T : IComparable<T>
66
{
77
// Inserting into a BSTree

source/code/projects/AVLTree_I/AVLTree/BTree.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ public bool IsEmpty()
8383
// its root node.
8484
public int Height()
8585
{
86-
int height = 0;
86+
int height = -1;
87+
// By convention, an empty tree
88+
// will have a height of -1.
8789
if (root != null)
8890
{
8991
height = root.Height;
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
public abstract class IBTree<T> : BTree<T>
5+
where T : IComparable<T>
6+
{
7+
protected int SubtreeBalance(Node nodeP)
8+
{
9+
// Will return
10+
// a negative number if subtree is right-heavy
11+
// a positive number if subtree is left-heavy
12+
// 0 if the subtree is perfectly balanced.
13+
int balance;
14+
if (nodeP == null)
15+
{
16+
balance = 0;
17+
}
18+
else if (nodeP.left == null && nodeP.right == null)
19+
{
20+
balance = 0;
21+
}
22+
else if (nodeP.left == null)
23+
{
24+
balance = -(nodeP.right.Height + 1);
25+
}
26+
else if (nodeP.right == null)
27+
{
28+
balance = nodeP.left.Height + 1;
29+
}
30+
else
31+
{
32+
balance = nodeP.left.Height - nodeP.right.Height;
33+
}
34+
return balance;
35+
}
36+
37+
/*
38+
* Before
39+
* nodeTop --> A
40+
* / \
41+
* nodeLeft--> B C
42+
* / \
43+
* D E <-- nodeLeft.right
44+
*
45+
* After
46+
* B
47+
* / \
48+
* D A
49+
* / \
50+
* E C
51+
*/
52+
protected Node RotateleftChild(Node nodeTop) // Aka left-left rotation
53+
{
54+
Node nodeLeft = nodeTop.left;
55+
nodeTop.left = nodeLeft.right;
56+
nodeLeft.right = nodeTop;
57+
return nodeLeft; // attached to caller as the new top of this subtree
58+
}
59+
60+
/*
61+
* Before
62+
* nodeTop --> A
63+
* / \
64+
* B C <-- nodeRight
65+
* / \
66+
* D E
67+
*
68+
* After
69+
* C
70+
* / \
71+
* A E
72+
* / \
73+
* B D
74+
*/
75+
protected Node RotaterightChild(Node nodeTop) // Aka right-right rotation
76+
{
77+
Node nodeRight = nodeTop.right;
78+
nodeTop.right = nodeRight.left;
79+
nodeRight.left = nodeTop;
80+
return nodeRight; // attached to caller as the new top of this subtree
81+
}
82+
83+
/*
84+
* Before
85+
* nodeP --> A
86+
* / \
87+
* B C
88+
* / \ / \
89+
* D E F G
90+
*
91+
* After RotaterightChild
92+
* A
93+
* / \
94+
* E C
95+
* / / \
96+
* B F G
97+
* /
98+
* D
99+
*
100+
* After
101+
* E
102+
* / \
103+
* B A
104+
* / \
105+
* D C
106+
* / \
107+
* F G
108+
*/
109+
110+
protected Node DoubleleftChild(Node nodeP)
111+
{
112+
nodeP.left = RotaterightChild(nodeP.left);
113+
return RotateleftChild(nodeP);
114+
}
115+
116+
protected Node DoublerightChild(Node nodeP)
117+
{
118+
nodeP.right = RotateleftChild(nodeP.right);
119+
return RotaterightChild(nodeP);
120+
}
121+
122+
// Helper methods, to demonstrate
123+
// tree rotations.
124+
public void Doubleleft()
125+
{
126+
if (root != null)
127+
{
128+
root = DoubleleftChild(root);
129+
}
130+
}
131+
132+
public void Doubleright()
133+
{
134+
if (root != null)
135+
{
136+
root = DoublerightChild(root);
137+
}
138+
}
139+
140+
public void Rotateright()
141+
{
142+
if (root != null)
143+
{
144+
root = RotaterightChild(root);
145+
}
146+
}
147+
148+
public void Rotateleft()
149+
{
150+
if (root != null)
151+
{
152+
root = RotateleftChild(root);
153+
}
154+
}
155+
156+
// The ToString method is simply here to help us debug.
157+
// It is not really pretty, but using pre-order and spaces
158+
// to make it easier to understand how the tree is
159+
// constructed. It also displays the height of the tree.
160+
161+
public override string ToString()
162+
{
163+
string returned = "Tree height: " + Height() + "\n";
164+
int tBalance = SubtreeBalance(root);
165+
returned += "Tree balance: " + tBalance;
166+
if (tBalance <= -2)
167+
{
168+
returned += " (Right-heavy)";
169+
}
170+
else if (tBalance >= 2)
171+
{
172+
returned += " (Left-heavy)";
173+
}
174+
returned += "\n";
175+
176+
if (root != null)
177+
{
178+
returned += Stringify(root, 0);
179+
}
180+
return returned;
181+
}
182+
183+
private string Stringify(Node nodeP, int height)
184+
{
185+
string returned = "";
186+
if (nodeP != null)
187+
{
188+
for (int i = 0; i < height; i++)
189+
{
190+
returned += " ";
191+
}
192+
returned += nodeP + "\n"; // Calls Node's ToString method.
193+
if (nodeP.left != null)
194+
{
195+
returned +=
196+
"L"
197+
+ " (h: "
198+
+ nodeP.left.Height
199+
+ ")"
200+
+ Stringify(nodeP.left, height + 1);
201+
}
202+
if (nodeP.right != null)
203+
{
204+
returned +=
205+
"R"
206+
+ " (h: "
207+
+ nodeP.right.Height
208+
+ ")"
209+
+ Stringify(nodeP.right, height + 1);
210+
}
211+
}
212+
return returned;
213+
}
214+
}

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,5 @@ static void Main()
4747
);
4848
bstree1.Doubleleft();
4949
Console.WriteLine(bstree1);
50-
51-
/*
52-
Console.WriteLine("Test");
53-
AVLTree<int> test = new AVLTree<int>();
54-
for (int i = 1; i <= 100; i++)
55-
{
56-
test.Insert(i);
57-
}
58-
Console.WriteLine(test);
59-
*/
6050
}
6151
}

source/lectures/data/AVLtrees.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,9 @@ which needs to be re-balanced using the `Doubleleftchild` method given below. In
6161
### Computing the height on the fly
6262

6363
It is also possible to compute the height of nodes "on the fly" instead of storing it.
64-
[This archive](./code/projects/AVLTree_I.zip) demonstrates this concept while additionally inheriting from the `BTree` class [explored previously](./lectures/data/trees).
64+
65+
[This archive](./code/projects/AVLTree_I.zip) demonstrates this concept while additionally
66+
67+
- inheriting from the `BTree` class [explored previously](./lectures/data/trees),
68+
- adding an `IBTree` class that allows you to explore the re-balancing methods more freely,
69+
- containing some examples showcasing how re-balancing works.

0 commit comments

Comments
 (0)