Download OrderedMap with a BST Data Structure - University of Arizona

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Lattice model (finance) wikipedia , lookup

Quadtree wikipedia , lookup

Red–black tree wikipedia , lookup

Interval tree wikipedia , lookup

B-tree wikipedia , lookup

Binary tree wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
Binary Search Trees
Rick Mercer, Allison Obourn, Marty Stepp
Binary Search Trees
 A Binary Search Tree (BST) data structure is a
binary tree with an ordering property
 BSTs are used to maintain order and faster
retrieval, insertion, and removal of individual
elements
 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 Tree
integers represent the keys
root
50
25
12
75
35
28
66
41
54
90
81
95
91
100
Are these BSTs?
only the keys are shown
root
50
Is this a BST?
25
12
75
45
root
66
50
Is this a BST?
25
12
90
75
55
73
90
BST Algorithms
only the keys are shown
 Think about an algorithm that search for 36
—
It is similar to Binary Search
root
 Start at root
50
t
25
12
75
36
65
90
adding Elements no duplicates can ever be added
The search element 36 < 50 so go left
root
50
t
25
12
75
36
65
90
adding Elements no duplicates can ever be added
36 > 25 so go right
36 found, stop, return true
root
50
t
25
12
75
36
65
90
adding Elements no duplicates can ever be added
If we were looking for 29, we would go to t.left and set t
to null, return false
root
50
t
25
12
75
36
65
What is the runtime of search in a BST?
90
Insert
 But 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
 Since trees are recursive data structures, we’ll
use recursion
9
First, example insert 11 elements
 What a binary search tree would look like if these values
were added in this order (first element is always at root)
root
50
20
75
98
80
31
150
39
23
11
77
50
20
11
75
98
31
23
39
80
77
150
Exercise
 Add a method add to the SearchTree class that
inserts an element into the BST.
 Add the new value in the proper place to maintain BST
root
ordering
bst.insert(49);
55
29
-3
87
42
49
60
91
An incorrect solution
public 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);
29
// else t.data.equals(value), so
// it's a duplicate (don't add)
}
—
Why doesn't this solution work?
-3
root
55
87
42
60
91
The x = change(x) pattern
Change a point?
 Will the assertions pass?
@Test
public void testChange() {
Point p = new Point(1, 2);
change(p);
assertEquals(3, p.x);
assertEquals(4, p.y);
}
p
public void change(Point thePoint) {
thePoint.x = 3;
thePoint.y = 4;
}
x
1
y
2
Change a point?
 Will the assertions pass?
@Test
public void testChange() {
Point p = new Point(1, 2);
change(p);
assertEquals(3, p.x);
assertEquals(4, p.y);
}
p
public void change(Point thePoint) {
thePoint = new Point(3, 4);
}
x
3
y
4
x
1
y
2
Changing references
 If a method dereferences a variable (with . ) and
modifies the object it refers to, that change will be seen
by the caller
void change(Point thePoint) {
thePoint.x = 3;
// affects the argument
thePoint.y = 4;
// affects the argument
 If a method reassigns a variable to refer to a new
object, that change will not affect the variable
void change(Point thePoint) {
thePoint = new Point(3, 4); // argument unchanged
thePoint = null;
// argument unchanged
Change point, version 3
 Will these assertions pass?
@Test
public void testChange() {
Point p = new Point(1, 2);
change(p);
assertEquals(3, p.x);
assertEquals(4, p.y);
}
p
public Point change(Point thePoint) {
thePoint = new Point(3, 4);
return thePoint;
}
x
3
y
4
x
1
y
2
Change point, version 4
 Will these assertions pass?
@Test
public void testChange() {
Point p = new Point(1, 2);
p = change(p);
assertEquals(3, p.x);
assertEquals(4, p.y);
}
p
public Point change(Point thePoint) {
thePoint = new Point(3, 4);
return thePoint;
}
x
1
y
2
x
3
y
4
The algorithmic pattern x = change(x);
 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 method
2. return the new (possibly changed) object from the method
3. 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;
 Also seen with strings, methods return a new String
s = s.toUpperCase();
s = s.substring(0, 3);
The problem was
 Much like with linked structure, if we only modify what
a local variable refers to, it won't change the collection
t
49
private void add(TreeNode t, E value) {
if (node == null) {
node = new TreeNode(value);
}
 In linked structures, how did we
29
actually modify the object?
 by changing first
-3 42
 by changing a Node's next field
root
55
87
60
91
Applying x = change(x)
 Methods that modify a tree should have the
following pattern:
— input (parameter): old state of the node
— output (return): new state of the node
node
before
parameter
your
method
return
node
after
 To change the tree, we must reassign
t
t.left
t.right
root
=
=
=
=
change(t, parameters);
change(t.left, parameters);
change(t.right, parameters);
change(root, parameters);
A correct solution
// Insert the given element into this BST
public void insert(E el) {
root = insert(root, el);
}
root
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);
55
29
87
return t;
-3
}
—
What happens when t is a leaf?
42
60
91