Download as pdf or txt
Download as pdf or txt
You are on page 1of 29

BINARY TREES

AND
BINARY SEARCH TREES

dddobach
Simple Recall
 Binary search?
 To search for an element in a sorted array,
1. Check if the sought element is the middle element. If it is,
we’ve found it!
2. If the sought element is smaller than the middle one, do the
same thing in the lower half of the array.
3. If the sought element is bigger than the middle one, do the
same thing in the higher half of the array
4. If the fragment of the array is empty, the sought element is
not there!
 This algorithm executes in logarithmic time!
BST
 Binary (search) trees will allow us to do the same
thing with a dynamic data structure

 RECALL: BINARY TREE!


Binary Tree

 Binary trees could be used to program the dynamic


version of binary search
 The root → element in the middle
 Nodes in  → smaller elements
 Nodes in  → bigger elements
Nodes in Java
class BinaryNode<E>{
private E element;
private BinaryNode<E> left;
private BinaryNode<E> right;
public BinaryNode(E e,
BinaryNode<E> lt,
BinaryNode<E> rt){
element = e;
left = lt;
right = rt;
}
...
}
Nodes in Java
 The size of a tree is the number of nodes in the
tree:
class BinaryNode<E>
{
public static <E> int size(BinaryNode <E>t){
if(t == null)
return 0;
else
return 1 + size(t.left) + size(t.right);
}
...
}
Nodes in Java
 The height of a tree is length of the path from the
root to the deepest leaf:
class BinaryNode<E>
{
public static <E> int height(BinaryNode<E> t){
if(t == null)
return -1;
else
return 1 + Math.max(height(t.left),
height(t.right));
}
...
}
Tree Traversals
 Preorder: First the root, then all nodes to the left,
then all nodes to the right.

public void printPreOrder(){


System.out.println(element);
if(left != null)
left.printPreOrder();
if(right != null)
right.printPreOrder();
}
Tree Traversals
 Inorder: First all nodes to the left (in inorder!), then
the root, and then all nodes to the right (in inorder!).

public void printInOrder(){

// ???
}
Binary Tree
 BinaryNode – done!
 What is a BinaryTree?
A BinaryNode (the root!) but it can be tested for
emptyness
 All operations are delegated to the root
Binary Tree
public class BinaryTree<E>{
private BinaryNode<E> root;

public BinaryTree(){
root = null;
}

public BinaryTree(E rootItem){


root = new BinaryNode(rootItem, null, null);
}
public boolean isEmpty(){
return root==null;
}
...
}
Binary Search Trees
 A Binary Tree, , has the search property if
  = ∅ , or
  is non-empty and
 All nodes in the left subtree are smaller than the root
 All nodes in the right subtree are bigger than the root
 The left subtree and the right subtree have the search
property
Binary Search Trees - Examples

39 48

43

39 48
Binary Search Trees - Observations
 If a binary tree has the search property (a binary
search tree), printing the elements in in order results
in a sorted output
 An iterator that produces the elements in in order
will produce them in an ordered fashion!
 There are many binary search trees that contain the
same elements
Binary Search Trees - Observations
 What shape is best?
BST – Naïve implementation
 Binary search trees can be implemented with binary
nodes
class BinarySearchTree<E extends Comparable<? super E>>{
BinaryNode<E> root;
public BinarySearchTree(){
root = null; }
public void insert(E x){
root = insert(x, root); }
public void remove(E x){
root = remove(x, root); }
public E find(E x){
return elementAt(find(x, root)); }
public boolean isEmpty(){
return root == null; }
...
}
Finding an element
 find – binary search
public E find(E x){
return elementAt(find(x, root));
}
private BinaryNode<E> find(E x, BinaryNode<E> t){
while(t != null){
if(x.compareTo(t.element)<0)
t = t.left;
else if(x.compareTo(t.element)>0)
t = t.right;
else
return t;
}
return null;
}
Finding an element
 find – binary search

private E elementAt(BinaryNode<E> t)
{
return t == null ? null : t.element;
}
Insert
 we have to find the proper place to add the new
node to the tree
public void insert(E x){
root = insert(x, root);
}
private BinaryNode<E> insert(E x, BinaryNode<E> t){
if(t == null)
t = new BinaryNode(x);
else if(x.compareTo(t.element) < 0)
t.left = insert(x, t.left);
else if(x.compareTo(t.element) > 0)
t.right = insert(x, t.right);
// else do nothing!
return t;
}
Example: Insertion
 Insert ‘5’

if(t == null)
t = new BinaryNode(x);
else if(x.compareTo(t.element) < 0)
t.left = insert(x, t.left);
else if(x.compareTo(t.element) > 0)
t.right = insert(x, t.right);
// else Duplicate: do nothing!
return t;
Example: Insertion
 Insert ‘5’
Remove
 To implement remove, we have to find the element
in the tree and reorganize the nodes left after
removal so that the tree continues to have the
search property
Remove
private BinaryNode<E> remove(E x, BinaryNode<E> t){
if( t == null )
throw new ItemNotFoundException(x.toString());
if( x.compareTo( t.element ) < 0 )
t.left = remove( x, t.left );
else if( x.compareTo( t.element ) > 0 )
t.right = remove( x, t.right );
else if( t.left != null && t.right != null ){
t.element = findMin( t.right ).element;
t.right = removeMin( t.right );
}else
t = ( t.left != null ) ? t.left : t.right;

return t;
}
Remove
findMax

if( t != null )
while( t.right != null )
t = t.right;

return t;
Example: Remove
 Remove ‘4’
Execution Time Analysis
 What can we say about the execution time of
find, insert and remove?
 How many nodes are visited?
 Because in all operations we choose one of the
subtrees, this depends on the shape of the tree!
Execution Time Analysis

At most 2!

At most 7!
Balanced Implementations
 Unbalanced
 nothing in the implementation that can guarantee how
the resulting tree looks like after a number of insertions
and deletions.
 O(log ( )) vs O(N)
 Proposals for balanced implementations
 AVL-Trees

 Red-Black Trees
 And others

You might also like