l14 Balancedbst Avl
l14 Balancedbst Avl
CSCI 104
Binary Search Trees and
Balanced Binary Search Trees
using AVL Trees
Mark Redekopp
David Kempe
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
2
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
3
BST-Find
• To find a node with a given key
– If node pointer is NULL, the key does NOT exist in the tree, STOP!
– Otherwise, check if current node's key equals the desired key
• If so, STOP! and return a pointer to that node
– If desired key is LESS-THAN current node's key, go LEFT
– If desired key is GREATER-THAN current node's key, go RIGHT
25
18 47
7 32 56
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
5
BST Insertion
• To insert an item walk the tree (go left if value is less than node, right if
greater than node) until you find an empty location, at which point you
insert the new value
• Practice: Build a BST from the data values below
Insertion Order: 25, 18, 47, 7, 20, 32, 56 Insertion Order: 7, 18, 20, 25, 32, 47, 56
BST Insertion
• To insert an item, walk the tree (go left if value is less than node, right if
greater than node) until you find an empty location, at which point you
insert the new value
• Practice: Build a BST from the data values below
• https://www.cs.usfca.edu/~galles/visualization/BST.html
Insertion Order: 25, 18, 47, 7, 20, 32, 56 Insertion Order: 7, 18, 20, 25, 32, 47, 56
25 7
18 47 18
20
7 20 32 56
25
32
47
A major topic we will talk about is algorithms
to keep a BST balanced as we do
insertions/removals 56
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
7
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
8
Predecessors Pred(50)
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
9
Predecessors Pred(50) = 30
• If left child exists, predecessor is the 50
right most node of the left subtree
20 60
• Else walk up the ancestor chain until
you traverse the first right child 10 30
pointer (find the first node who is a
25
right child of his parent…that parent is
Pred(25)=20
the predecessor)
50
– If you get to the root w/o finding a node
who is a right child, there is no 20 60
predecessor
10 30
25
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
10
Successors Succ(20)
• If right child exists, successor is the 50
left most node of the right subtree
20 60
• Else walk up the ancestor chain until
you traverse the first left child pointer 10 30
(find the first node who is a left child
25
of his parent…that parent is the
Succ(30)
successor)
50
– If you get to the root w/o finding a node
who is a left child, there is no successor 20 60
10 30
25
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
11
Successors Succ(20) = 25
• If right child exists, successor is the 50
left most node of the right subtree
20 60
• Else walk up the ancestor chain until
you traverse the first left child pointer 10 30
(find the first node who is a left child
25
of his parent…that parent is the
Succ(30)=50
successor)
50
– If you get to the root w/o finding a node
who is a left child, there is no successor 20 60
10 30
25
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
12
BST Removal
• How we remove is based on the number of children the node has…
– First find the value to remove by walking the tree
– 0 children: If the value is in a leaf node, simply remove that leaf node
– 1 child: Promote the child into the node's location
– 2 children: Swap the value with its in-order successor or predecessor and then
remove from its new location
• We can maintain the BST properties by putting a value's successor or predecessor in its
place
• After swap, we have converted to 0-children or 1-child case (i.e. non-leaf node's
successor or predecessor is guaranteed to not have 2 children) which we then perform
Remove 25 Remove 30 Remove 20
50
Either swap with
50 50 50 predecessor
10 60
20 60 20 60 20 60
20 30 50
10 30 10 30 10 30 25 60
5 25 35
25 25 5 25 35
…or swap with
10 30
Leaf node so 1-Child so just 20 is a non-leaf so can't delete it
where it is…swap w/ successor successor
just delete it 22 promote child
or predecessor 5 20 35
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
13
// Node definition
– Balanced: _________ template <typename T>
struct TNode
– Unbalanced: _________
{
T val;
TNode *left, *right;
• Removal };
Tnode *parent;
• Find/Search
public:
BTree();
~BTree();
– Balanced: __________ virtual bool empty();
virtual void insert(const T& v);
virtual void remove(const T& v);
– Unbalanced: __________ virtual T* find(const T& v);
protected:
TNode<T>* root_;
};
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
14
BST Efficiency
• Insertion
#include<iostream>
// Node definition
– Balanced: O(log n) template <typename T>
struct TNode
– Unbalanced: O(n)
{
T val;
TNode *left, *right;
• Removal };
Tnode *parent;
• Find/Search
public:
BTree();
~BTree();
– Balanced : O(log n) virtual bool empty();
virtual void insert(const T& v);
virtual void remove(const T& v);
– Unbalanced: O(n) virtual T* find(const T& v);
protected:
TNode<T>* root_;
};
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
15
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
16
TREE ROTATIONS
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
17
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
18
z x
(-inf, z) (z, inf) (-inf, x) (x, inf)
y d a y
(-inf, y) (y,z) (x, y) (y, inf)
x c b z
(-inf, x) (x,y) (y,z) (z,inf)
a b c d
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
19
Right Rotation
• Define a right rotation as taking a left child, making it
the parent and making the original parent the new right
child
• Where do subtrees a, b, c and d belong?
– Use their ranges to reason about it…
(-inf, inf)
z Right
y
rotate of
(-inf, z) (z, inf)
z
y d x z
(-inf, y) (y,z)
c ___ ___ ___ ___
x
(-inf, x) (x,y)
a b
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
20
Right Rotation
• Define a right rotation as taking a left child, making it
the parent and making the original parent the new right
child
• Where do subtrees a, b, c and d belong?
– Use their ranges to reason about it…
(-inf, inf)
z Right
y
rotate of
(-inf, z) (z, inf)
z
y d x z
(-inf, y) (y,z)
c a b c d
x
(-inf, x) (x,y) (y,z) (z, inf)
(-inf, x) (x,y)
a b
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
21
Left Rotation
• Define a left rotation as taking a right child, making it
the parent and making the original parent the new left
child
• Where do subtrees a, b, c and d belong?
– Use their ranges to reason about it…
(-inf, inf)
y x
Left
rotate of (-inf, x) (x, inf)
x
x z a y
(x, y) (y, inf)
___ ___ ___ ___ b z
(y,z) (z,inf)
c d
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
22
Left Rotation
• Define a left rotation as taking a right child, making it
the parent and making the original parent the new left
child
• Where do subtrees a, b, c and d belong?
– Use their ranges to reason about it…
(-inf, inf)
y x
Left
rotate of (-inf, x) (x, inf)
x
x z a y
(x, y) (y, inf)
a b c d b z
(-inf, x) (x,y) (y,z) (z, inf)
(y,z) (z,inf)
c d
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
23
Rotations
• Define a right rotation as taking a left child, making it
the parent and making the original parent the new right
child
• Where do subtrees a, b, and c belong?
– Use their ranges to reason about it…
(-inf, inf) (-inf, inf)
y x
Right rotate
(-inf, y) (y, inf) of y (-inf, x) (x, inf)
x c a y
(-inf, x) (x,y) (x, y) (y, inf)
a b Left rotate b c
of x
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
24
Implementing Rotations
• Take a moment and identify how many and which
pointers need to be updated to perform the below
right rotation
p 1.
p
2.
(-inf, inf) (-inf, inf)
3.
y x 4.
Right rotate
(-inf, y) (y, inf) of y (-inf, x) (x, inf)
x c a y
(-inf, x) (x,y) (x, y) (y, inf) …
a b b c
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
25
z
y
Right rotate
of z
y
h h x z h+1
h+2
x c
h
h h h h
h h
Let's always specify the parent node involved in a rotation (i.e. the
node that is going to move DOWN).
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
26
AVL TREES
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
27
AVL Trees
• A binary search tree where the height difference between left and right subtrees
of a node is at most 1
– Binary Search Tree (BST): Left subtree keys are less than the root and right subtree keys
are greater
• Two implementations:
– Height: Just store the height of the tree rooted at that node
– Balance: Define b(n) as the balance of a node = Right – Left Subtree Height
• Legal values are -1, 0, 1
• Balances require at most 2-bits if we are trying to save memory.
• Let's use balance for this lecture.
-1 20
4 20
Balance
factors
0 10 -1 30
3 10 2 30
05 1 12 0 25
2 5 2 12 1 25
0 15
1 15 0 3 0 8
1 3 1 8
AVL Tree storing Heights
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed. AVL Tree storing balances
28
0 12 -1 12 +112 0 12
0 10 0 20 0 10 0 20
Losing Balance
• If our parent is NOT out of balance, is it possible our
grandparent is out of balance?
• Sure, so we need a way to re-balance it
-2 2
-1 15 1 10
-1
0 12 -1
0 15
0 10
0 12
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
30
To Zig or Zag
• The rotation(s) required to g
0 12
g
-2 20 2 10
balance a tree is/are
p p
dependent on the -1 12 0 10 0 20 1 12
grandparent, parent, child
0 10 0 20
relationships
Left-left or Right-right
• We can refer to these as (a.k.a. Zig-zig)
the zig-zig (left-left or right- [Single left/right rotation at grandparent]
right) case and zig-zag case
(left-right or right-left)
g
• Zig-zig requires 1 rotation 0 12
g
-2 20 2 10
• Zig-zag requires 2 rotations p p
0 10 0 20
(first converts to zig-zig) 1 10 -1 20
0 12 0 12
Left-right or Right-left
(a.k.a. Zig-zag)
[Left/right rotation at parent followed by rotation in
opposite direction at grandparent]
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
31
Disclaimer
• There are many ways to structure an
implementation of an AVL tree…the following
slides represent just 1
– Focus on the bigger picture ideas as that will allow
you to more easily understand other
implementations
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
32
Insert(n)
• If empty tree => set n as root, b(n) = 0, done!
• Else insert n (by walking the tree to a leaf, p, and
inserting the new node as its child), set balance
-1 12
to 0, and look at its parent, p
0 10 0 20
– If b(p) was -1, then b(p) = 0. Done!
– If b(p) was +1, then b(p) = 0. Done! 1 12
-1
0 12
0 10
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
33
Insert-fix(p, n)
General Idea:
Work up ancestor
• Precondition: p and n are balanced: {-1,0,-1} chain updating
• Postcondition: g, p, and n are balanced: {-1,0,-1} balances of the
ancestor chain or
• If p is null or parent(p) is null, return fix a node that is
• Let g = parent(p) out of balance.
Insertion
• Insert 10, 20, 30, 15, 25, 12, 5, 3, 8
Empty Insert 10 Insert 20 Insert 30 Zig-zig =>
10 violates balance b(g) = b(p) = 0
1 10 2 10 g 0 20
0 10
0 20
p 0 10 0 30
1 20
n
0 30
1 10 0 30 -1 30
g -1 30 0 12 -1 30
1 10 2 10
0 15 0 15 0 25 p -1 15 0 25 0 10 0 15 0 25
0 12 n
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
35
Insertion
• Insert 10, 20, 30, 15, 25, 12, 5, 3, 8
Zig-zig =>
Insert 5 Insert 3 -1 20 b(g) = b(p) = 0
-1 20 -1 20
-1 12 -1 30 -1 12 -1 30 -1 12 -1 30
g
-110 0 15 0 25 -210 0 15 0 25 05 0 15 0 25
p
-1 5 3 0 10
0 5 0
0 3
-2 12 -1 30 0 10 -1 30
+1 5 0 15 0 25 05 1 12 0 25
0 3 -1 10 n 0 3 0 8 0 15
0 8
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
36
Insertion Exercise 1
• Insert key=28
-1 20
0 10 -1 30
05 1 12 0 25
0 15
0 3 0 8
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
37
Insertion Exercise 2
• Insert key=17
-1 20
0 10 -1 30
05 1 12 0 25
0 15
0 3 0 8
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
38
Insertion Exercise 3
• Insert key=2
-1 20
0 10 -1 30
05 1 12 0 25
0 15
0 3 0 8
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
39
Remove Operation
• Remove operations may also require rebalancing via
rotations
• The key idea is to update the balance of the nodes
on the ancestor pathway
• If an ancestor gets out of balance then perform
rotations to rebalance
– Unlike insert, performing rotations during removal does
not mean you are done, but need to continue recursing
• There are slightly more cases to worry about but not
too many more
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
40
Remove 25
-1 20 0 10
-2 20
-1 10 -1 30 0 20
-1 10 0 30 05
0 5 0 12 0 25 0 3 0 8 0 12 0 30
05 0 12
0 3 0 8 0 3 0 8
Remove
• Find node, n, to remove by walking the tree
• If n has 2 children, swap positions with in-order successor (or
predecessor) and perform the next step
– Recall if a node has 2 children we swap with its successor or predecessor who
can have at most 1 child and then remove that node
• Let p = parent(n)
• If p is not NULL,
– If n is a left child, let diff = +1
– If n is a left child to be removed, the right subtree now has greater height, so add diff = +1 to
balance of its parent
– if n is a right child, let diff = -1
– If n is a right child to be removed, the left subtree now has greater height, so add diff = -1 to
balance of its parent
– diff will be the amount added to updated the balance of p
• Delete n and update pointers
• “Patch tree” by calling removeFix(p, diff);
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
42
RemoveFix(n, diff)
• If n is null, return
• Compute next recursive call's arguments now before altering the tree
– Let p = parent(n) and if p is not NULL let ndiff (nextdiff) = +1 if n is a left child and -1 otherwise
• Assume diff = -1 and follow the remainder of this approach, mirroring if diff = +1
• Case 1: b(n) + diff == -2
– [Perform the check for the mirror case where b(n) + diff == +2, flipping left/right and -1/+1]
– Let c = left(n), the taller of the children
– Case 1a: b(c) == -1 // zig-zig case
• rotateRight(n), b(n) = b(c) = 0, removeFix(p, ndiff)
– Case 1b: b(c) == 0 // zig-zig case
• rotateRight(n), b(n) = -1, b(c) = +1 // Done! Note:
– Case 1c: b(c) == +1 // zig-zag case p = parent of n
• Let g = right(c) n = current node
• rotateLeft(c) then rotateRight(n) c = taller child of n
• If b(g) was +1 then b(n) = 0, b(c) = -1, b(g) = 0
g = grandchild of n
• If b(g) was 0 then b(n) = 0, b(c) = 0, b(g) = 0
• If b(g) was -1 then b(n) = +1, b(c) = 0, b(g) = 0
• removeFix(p, ndiff);
• Case 2: b(n) + diff == -1: then b(n) = -1; // Done!
• Case 3: b(n) + diff == 0: then b(n) = 0, removeFix(p, ndiff)
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
43
h+2 h+1
p n g
h
(-)
h+1 n c
h+1 h or h or h+1 h
or h h-1 h-1 or h
h or h or
h-1 h-1
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
44
h+2
p p g
h
(-)
c h+1 n
h h h or h or h
h-1 h-1
h or h or
h-1 h-1
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
45
Remove Examples
Remove 15
-1 20 -1 20
n
0 10 -1 30 -1 10 -1 30
n
0 5 1 12 0 25 05 0 12 0 25
0 15 0 15
0 3 0 8 0 3 0 8
Remove 3
-1 20
-1 20
-1 10 -1 30
-1 10 -1 30
n n
05 0 12 0 25 15 0 12 0 25
0 3 0 8 0 3 0 8
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
46
Remove Examples
Remove 30
n
-1 20 -1 20
n -1 10 0 25
-1 10 -1 30
0 12 1 5 0 12
1 5 0 25
0 8 0 8
c n
-1 10 0 25 0 20
1 5
g
1 5 0 12 0 12 0 25
0 8
0 8
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
47
Remove Examples
Remove 20
n n n
-1 20 -1 22 -2 22
succ(n)
c
1 10 1 22 1 10 1 20 0 25
1 10
g
0 5 -1 12 0 25 0 5 -1 12 0 25
0 5 -1 12
0 11 0 11 0 11
c n
0 10 1 22
0 5 0 11 0 25
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
48
Remove Example 1
Remove 8
-1 20
1 10 -1 30
-1 8 -1 15 1 25 0 35
05 1 12 0 17 028
0 14
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
49
Remove Example 1
Remove 8 Zig-zag & b(g) = 0 =>
b(n) = -1, b(c) = 0
p
-1 20 -1 20 -1 20
n g
1 10 -1 30 2 10 -1 30 0 12 -1 30
c n c
-1 8 -1 15 1 25 0 35 0 5 -1 15 1 25 0 35 -1 10 0 15 1 25 0 35
g 1
05 1 12 0 17 028 12 0 17 028 0 14 0 17 028
0 5
0 14 0 14
n 0
20
0 12 -1 30
-1 10 0 15 1 25 0 35
0 0 14 0 17 028
5
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
50
Remove Example 2
Remove 10
-1 20
1 10 -1 30
-1 8 -1 15 1 25 0 35
05 -1 12 0 17 028
0 11
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
51
Remove Example 2
Remove 10
-1 20 -1 20
-1 30 1 11 -1 30
1 10
-1 15 -1 8 -1 15 1 25 0 35
-1 8 1 25 0 35
n
05 -1 12 0 17 028
05 0 12 0 17 028
0 11 0 10
n
-1 20 -1 20 0 20
n
-1 30 -1 30 1 11 -1 30
1 11 0 11
n
-1 8 0 15 1 25 0 35 -1 8 0 15 1 25 0 35 -1 8 0 15 1 25 0 35
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
52
Remove Example 3
Remove 30
-1 20
1 10 -1 30
-1 8 -1 15 1 25 0 35
05 1 12 0 17 028
0 14
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
53
1 10 -1 30 1 10 -1 35
-1 8 -1 15 1 25 0 35 -1 8 -1 15 1 25 0 30
05 1 12 0 17 028 05 1 12 0 17 028
0 14 0 14
-1 20 n -2
20
n c
1 10 -2 35 1 10 0 28
g
c
-1 8 -1 15 1 25 -1 8 -1 15 0 25 0 35
g
05 1 12 0 17 028 05 1 12 0 17
0 14 0 14
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
54
0 10 1 20
1 12 0 17 0 28
-1 8
05 0 14 0 25 0 35
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
55
Remove Exercise
Remove 35
-1 20
1 10 -1 30
-1 8 -1 15 1 25 0 35
05 1 12 0 17 028
0 14
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
56
Online Tool
• https://www.cs.usfca.edu/~galles/visualization/AVLtree.html
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
57
FOR PRINT
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
58
Insert(n)
• If empty tree => set n as root, b(n) = 0, done!
• Else insert n (by walking the tree to a leaf, p, and
inserting the new node as its child), set balance
-1 12
to 0, and look at its parent, p
0 10 0 20
– If b(p) was -1, then b(p) = 0. Done!
– If b(p) was +1, then b(p) = 0. Done! 1 12
-1
0 12
0 10
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
59
Insert-fix(p, n)
General Idea:
Work up ancestor
• Precondition: p and n are balanced: {-1,0,-1} chain updating
• Postcondition: g, p, and n are balanced: {-1,0,-1} balances of the
ancestor chain or
• If p is null or parent(p) is null, return fix a node that is
• Let g = parent(p) out of balance.
Remove
• Find node, n, to remove by walking the tree
• If n has 2 children, swap positions with in-order successor (or
predecessor) and perform the next step
– Recall if a node has 2 children we swap with its successor or predecessor who
can have at most 1 child and then remove that node
• Let p = parent(n)
• If p is not NULL,
– If n is a left child, let diff = +1
– If n is a left child to be removed, the right subtree now has greater height, so add diff = +1 to
balance of its parent
– if n is a right child, let diff = -1
– If n is a right child to be removed, the left subtree now has greater height, so add diff = -1 to
balance of its parent
– diff will be the amount added to updated the balance of p
• Delete n and update pointers
• “Patch tree” by calling removeFix(p, diff);
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
61
RemoveFix(n, diff)
• If n is null, return
• Compute next recursive call's arguments now before altering the tree
– Let p = parent(n) and if p is not NULL let ndiff (nextdiff) = +1 if n is a left child and -1 otherwise
• Assume diff = -1 and follow the remainder of this approach, mirroring if diff = +1
• Case 1: b(n) + diff == -2
– [Perform the check for the mirror case where b(n) + diff == +2, flipping left/right and -1/+1]
– Let c = left(n), the taller of the children
– Case 1a: b(c) == -1 // zig-zig case
• rotateRight(n), b(n) = b(c) = 0, removeFix(p, ndiff)
– Case 1b: b(c) == 0 // zig-zig case
• rotateRight(n), b(n) = -1, b(c) = +1 // Done! Note:
– Case 1c: b(c) == +1 // zig-zag case p = parent of n
• Let g = right(c) n = current node
• rotateLeft(c) then rotateRight(n) c = taller child of n
• If b(g) was +1 then b(n) = 0, b(c) = -1, b(g) = 0
g = grandchild of n
• If b(g) was 0 then b(n) = 0, b(c) = 0, b(g) = 0
• If b(g) was -1 then b(n) = +1, b(c) = 0, b(g) = 0
• removeFix(p, ndiff);
• Case 2: b(n) + diff == -1: then b(n) = -1; // Done!
• Case 3: b(n) + diff == 0: then b(n) = 0, removeFix(p, ndiff)
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
62
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
63
Insert
• Root => set balance, done!
• Insert, v, and look at its parent, p
– If b(p) = -1, then b(p) = 0. Done!
– If b(p) = +1, then b(p) = 0. Done!
– If b(p) = 0, then update b(p) and call insert-fix(p)
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
64
Insert-Fix
• For input node, v
– If v is root, done.
– Invariant: b(v) = {-1, +1}
• Find p = parent(v) and assume v = left(p) [i.e. left child]
– If b(p) = 1, then b(p) = 0. Done!
– If b(p) = 0, then b(p) = -1. Insert-fix(p).
– If b(p) = -1 and b(v) = -1 (zig-zig), then b(p) = 0, b(v) = 0, rightRotate(p)
Done!
– If b(p) = -1 and b(v) = 1 (zig-zag), then
• u = right(v), b(u) = 0, leftRotate(n), rightRotate(p)
• If b(u) = -1, then b(v) = 0, b(p) = 1
• If b(u) = 1, then b(v) = -1, b(p) = 0
• Done!
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
65
Remove
• Let n = node to remove (perform BST find)
• If n has 2 children, swap positions with in-order successor (or
predecessor) and perform the next step
– If you had to swap, let n be the node with the original value that just
swapped down to have 0 or 1 children guaranteed
• Let p = parent(n)
• If n is not in the root position (i.e. p is not NULL) determine its
relationship with its parent
– If n is a left child, let diff = +1
– if n is a right child, let diff = -1
• Delete n and "patch" the tree (update pointers including root)
• removeFix(p, diff);
© 2022 by Mark Redekopp. This content is protected and may not be shared, uploaded, or distributed.
66
RemoveFix(n, diff)
• If n is null, return
• Compute next recursive call's arguments now before we alter the tree
– Let p = parent(n) and if p is not NULL let ndiff = +1 if n is a left child and -1 otherwise
• Assume diff = -1 and follow the remainder of this approach, mirroring if diff = +1
• If (n.balance + diff == -2)
– [Perform the check for the mirror case where n.balance + diff == +2, flipping left/right and -1/+1]
– Let c = left(n), the taller of the children
Note:
– If c.balance == -1 or 0 (zig-zig case)
p = parent of n
• rotateRight(n)
n = current node
• if c.balance was -1 then n.balance = c.balance = 0, removeFix(p, ndiff)
c = taller child of n
• if c.balance was 0 then n.balance = -1, c.balance = +1, done!
g = grandchild of n
– else if c.balance == 1 (zig-zag case)
• Let g = right(c)
• rotateLeft(c) then rotateRight(n)
• If g.balance was +1 then n.balance = 0, c.balance = -1, g.balance = 0
• If g.balance was 0 then n.balance = c.balance = 0, g.balance = 0
• If g.balance was -1 then n.balance = +1, c.balance = 0, g.balance = 0
• removeFix(p, ndiff);
• else if (n.balance + diff == -1) then n.balance = -1, done!
© 2022 by•Mark Redekopp.
else (if Thisn.balance
content is protected +
anddiff
may not== 0) n.balance
be shared, = 0, removeFix(p, ndiff)
uploaded, or distributed.