Binary Search Trees
Rick Mercer, Allison Obourn, Marty Stepp
Binary Search Trees
w A Binary Search Tree (BST) data structure is a binary tree with an ordering property
w BSTs are used to maintain order and faster retrieval, insertion, and removal of individual elements
w A Binary Search Tree (BST) is— an empty tree— consists of a node called the root, and two children, left
and right, each of which are themselves binary search trees. Each BST contains a key at the root that is greater than all keys in the left BST while also being less than all keys in the right BST. Key fields are unique, duplicates not allowed.
A Binary Search Treeintegers represent the keys
50
7525
12 35
28 41
66 90
81 95
91 100
54
root
Are these BSTs?only the keys are shown
50
7525
12 45 66 90
50
7525
12 55 73 90
Is this a BST?
Is this a BST?
root
root
BST Algorithms only the keys are shown
w Think about an algorithm that search for 36— It is similar to Binary Search
w Start at root
50
7525
12 36 65 90
t
root
adding Elements no duplicates can ever be added
The search element 36 < 50 so go left
50
7525
12 36 65 90
t
root
adding Elements no duplicates can ever be added
36 > 25 so go right36 found, stop, return true
50
7525
12 36 65 90
t
root
adding Elements no duplicates can ever be added
If we were looking for 29, we would go to t.left and set tto null, return false
What is the runtime of search in a BST?
50
7525
12 36 65 90
t
root
Insert
wBut how did we build this tree?— Don’t want to hard code it— There is no prefix expression to be used— Could be recursive— Could be iterative
wSince trees are recursive data structures, we’ll use recursion
9
First, example insert 11 elementsw What a binary search tree would look like if these values
were added in this order (first element is always at root)
50 207598 803115039231177
50
20 75
80
9811
39
31
15023
77
root
Exercisew Add a method add to the SearchTree class that
inserts an element into the BST.w Add the new value in the proper place to maintain BST
orderingbst.insert(49);
9160
8729
55
42-3
root
49
An incorrect solutionpublic void insert(E element) {add(root, element);
}
private void add(TreeNode t, E value) {if (t == null) {t = new TreeNode(value);
else if (value.compareTo(t.data) < 0)add(t.left, value);
else if (value.compareTo(t.data) > 0)add(t.right, value);
// else t.data.equals(value), so// it's a duplicate (don't add)
}
— Why doesn't this solution work?9160
8729
55
42-3
root
The x = change(x) pattern
Change a point?
wWill the assertions pass?@Testpublic void testChange() {
Point p = new Point(1, 2);change(p);assertEquals(3, p.x);assertEquals(4, p.y);
}
public void change(Point thePoint) {thePoint.x = 3; thePoint.y = 4;
}
2y1xp
Change a point?
w Will the assertions pass?@Testpublic void testChange() {
Point p = new Point(1, 2);change(p);assertEquals(3, p.x);assertEquals(4, p.y);
}
public void change(Point thePoint) {thePoint = new Point(3, 4);
}
2y1xp
4y3x
Changing referencesw If a method dereferences a variable (with . ) and
modifies the object it refers to, that change will be seen by the callervoid change(Point thePoint) {
thePoint.x = 3; // affects the argumentthePoint.y = 4; // affects the argument
w If a method reassigns a variable to refer to a new object, that change will not affect the variablevoid change(Point thePoint) {
thePoint = new Point(3, 4); // argument unchangedthePoint = null; // argument unchanged
Change point, version 3w Will these assertions pass?@Testpublic void testChange() {
Point p = new Point(1, 2);change(p);assertEquals(3, p.x);assertEquals(4, p.y);
}
public Point change(Point thePoint) {thePoint = new Point(3, 4);return thePoint;
}
2y1xp
4y3x
Change point, version 4w Will these assertions pass?
@Testpublic void testChange() {Point p = new Point(1, 2);p = change(p);assertEquals(3, p.x);assertEquals(4, p.y);
}
public Point change(Point thePoint) {thePoint = new Point(3, 4);return thePoint;
}
2y1xp
4y3x
The algorithmic pattern x = change(x);w If you want to write a method that can change the object
that a variable refers to, you must do three things:1. pass in the original state of the object to the method2. return the new (possibly changed) object from the method3. re-assign the caller's variable to store the returned result
p = change(p);public Point change(Point thePoint) {thePoint = new Point(99, -1);return thePoint;
w Also seen with strings, methods return a new String s = s.toUpperCase();s = s.substring(0, 3);
The problem wasw Much like with linked structure, if we only modify what
a local variable refers to, it won't change the collection
private void add(TreeNode t, E value) {if (node == null) {node = new TreeNode(value);
}
w In linked structures, how did weactually modify the object?� by changing first� by changing a Node's next field
9160
8729
55
42-3
root
49t
Applying x = change(x)w Methods that modify a tree should have the
following pattern:— input (parameter): old state of the node— output (return): new state of the node
yourmethod
nodebefore
nodeafter
parameter return
w To change the tree, we must reassignt = change(t, parameters);t.left = change(t.left, parameters);t.right = change(t.right, parameters);root = change(root, parameters);
A correct solution
// Insert the given element into this BSTpublic void insert(E el) {root = insert(root, el);
}
private TreeNode insert(TreeNode t, E el) {if (t == null)
t = new TreeNode(el);else if (el.compareTo(t.data) < 0)
t.left = insert(t.left, el);else
t.right = insert(t.right, el);
return t;}
— What happens when t is a leaf?9160
8729
55
42-3
root