Download CS II: Data Structures Discussion worksheet: Week 9

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

Linked list wikipedia , lookup

Quadtree wikipedia , lookup

Lattice model (finance) 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
CS II: Data Structures
Discussion worksheet: Week 9
Binary Search Trees, Balanced Trees
Part 1
1. Draw out a Binary Search Tree of the following nodes in this order, starting with 44 as
the root:
44, 17, 88, 8, 32, 65, 28, 21, 29, 54, 97, 82, 76, 93, 80
44
17
88
2. Write out a recursive method that searches for a number in a binary search tree. Lastly,
if the number is found, return the node, else return null.
private class Node {
private Key key;
private Value val;
private Node left, right;
private int size;
//
//
//
//
sorted by key
associated data
left and right subtrees
number of nodes in subtree
}
private Node search(int num, Node node){
if(node == null){
return null;
}
else if(node.val == num){
return node;
}
else if(node.val < num){
return search(num, node.left);
}
else{
return search(num, node.right);
}
}
3.
Using your search method above, write a list of the recursive calls using the tree from
Question 1. You are to search for 93. In place of the second argument, Node node,
write the current value you are on. The first call is search(93, 44) because 44 is the root
node.
search(93,44);
search(93,88);
search(93,97);
search(93,93);
4. Reflection: What is the worst-case running time of searching this tree?
O(h) which is the height of the tree
If the tree is balanced, then you are search for an element in O(log n)
time which is the height of the tree h. If the tree isn’t balanced,
then searching for an element at worst takes linear time.
Part 2
5. Now write an algorithm that inserts the element in the tree like you illustrated above in
question 1. Use the BST class below and fill in the put method.
public class BST<Key extends Comparable<Key>, Value> {
private Node root;
// root of BST
private class Node {
private Key key;
private Value val;
private Node left, right;
private int size;
//
//
//
//
sorted by key
associated data
left and right subtrees
number of nodes in subtree
public Node(Key key, Value val, int size) {
this.key = key;
this.val = val;
this.size = size;
}
}
private Node put(Node x, Key key, Value val) {
if (x == null) return new Node(key, val, 1);
int cmp = key.compareTo(x.key);
if(cmp < 0){
x.left = put(x.left, key, val);
}
else if(cmp > 0){
x.right = put(x.right, key, val);
}
else{
x.val
= val;
}
x.size = 1 + size(x.left) + size(x.right);
return x;
}
}
Part 3
6. Do the same as Part 1 Question 1 with this data set:
150, 140, 50, 30, 12, 9, 6
7. Reflection: What is the worst case running time of insertion and searching for an
element in this tree?
O(n), because this tree isn’t balance.
8. Write a method that would create a balance binary tree from a sorted array. Below is a
public method, as well as a private method to use as a recursive helper function.
public Node sortedArrayToBST(int arr[]) {
return sortedArrayToBST(arr, 0, arr.length-1);
}
private Node sortedArrayToBST(int arr[], int start, int end) {
if (start > end) return null;
// same as (start+end)/2, avoids overflow.
int mid = start + (end - start) / 2;
Node node = new Node(arr[mid]);
node.left = sortedArrayToBST(arr, start, mid-1);
node.right = sortedArrayToBST(arr, mid+1, end);
return node;
}
9. Reflection: For a balanced binary search tree, what is the worst case running time of
insert() and search() for an element in this tree?
O(log n) because now you can drop half of the input for each method call as long as the
tree is balanced.
Part 4
10. Next implement remove for our Binary Search Tree, you do not have to leave the tree
balanced: The String key is the value of the node that we are trying to remove. The
Node pos is holder/pointer node for your recursive calls.
public void remove (String key, Node pos)
{
if (pos == null) return;
/* Cycle through until you find the node to delete */
if (key.compareTo(pos.key) < 0){
remove (key, pos.left);
}
else if (key.compareTo(pos.key) > 0){
remove (key, pos.right);
}
else {
/* We found the node to delete */
//Case 1: Node to delete has left and right children
if (pos.left != null && pos.right != null)
{
//Note, it is good coding practice to put these helper
methods in a separate method.
//At most, your method shouldn't be over 10 or so statements,
you should refactor to make
//methods smaller or legible for other users.
/* pos has two children */
Node maxFromLeft = pos.left;
while(maxFromLeft.right != null){
maxFromLeft = temp.right;
}
//"Replacing " pos.key " with " maxFromLeft.key
pos.key = maxFromLeft.key;
//Remove the node we just swapped into the place of the node
to delete
remove (maxFromLeft.key, pos.left);
}
//Case 2: Node to delete has left children
else if(pos.left != null) {
/* node pointed by pos has at most one child */
Node trash = pos;
//"Promoting " pos.left.key " to replace " pos.key
pos = pos.left;
trash = null;
}
//Case 3: Node to delete has right children
else if(pos.right != null) {
/* node pointed by pos has at most one child */
Node trash = pos;
/* "Promoting " pos.right.key" to replace " pos.key */
pos = pos.rightChild;
trash = null;
}
//Case 4: Node to delete is the root
else {
pos = null;
}
}
}