Download Presentation
## Binary Trees

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -

**Binary Trees**• Sets and Maps in Java are also available in tree-based implementations • A Tree is – in this context – a data structure which allows fast O(log(n)) insertion, deletion and lookup of elements • Furthermore, a Tree maintains an ordering of the elements RHS – SWC**Binary Trees**• A Tree can be perceived as a generali-sation of a Linked List: RHS – SWC**Binary Trees**• A Tree consists of nodes, which contain data, and references to (up to) n other nodes • n = 1: Linked List • n = 2: Binary Tree • If node A refers to node B, we say that • Node A is the parent of node B • Node B is a child of node A RHS – SWC**Binary Trees**• The node at the top of the tree is called the root node, and does not have a parent • The nodes at the edge of the tree are called leaves, and do not have any children Root Leaf Leaf RHS – SWC**Binary Trees**• For a node A, we call the set of nodes consisting of the children of A, and the children of the children of A, and so forth, the descendants of A Descendants of 5 RHS – SWC**Binary Search Trees**• A Binary Tree is thus a special type of Tree, where each node has (up to) 2 children • A Binary Search Tree has some additio-nal properties • The data in each node must be of the type Comparable (i.e. implement the interface) • The nodes must obey certain ordering rules RHS – SWC**Binary Search Trees**• Ordering rules for nodes in a binary search tree: • The data values of all descendants to the left of any node are less than the data value stored in that node • The data values of all descendants to the right of any node are larger than the data value stored in that node • No duplicates allowed RHS – SWC**Binary Search Trees**All these nodes are larger than 10 All these nodes are smaller than 10 RHS – SWC**Binary Search Trees**• Searching in a Binary Search Tree is quite fast: O(log(n)) • How do we check if a value v is found in the tree? • Set current node N = root node • If value(N.data) = v, we are done, else • If value(N.data) < v, set N = left child (stop if null) • If value(N.data) > v, set N = right child (stop if null) • Go to 2 RHS – SWC**Binary Search Trees**public class BinarySearchTree { private Node root; private class Node {...} public BinarySearchTree() {root = null; } publicboolean contains(Comparable data) {...} publicvoid add(Comparable data) {...} publicvoid delete(Comparable data) {...} } RHS – SWC**Binary Search Trees**// NOTE: Inner class, public instance fields OK private class Node { public Comparable data; public Node left; public Node right; public Node(Comparable data) {...} publicboolean contains(Comparable data) {...} publicvoid add(Comparable data) {...} publicvoid delete(Comparable data) {...} } RHS – SWC**Binary Search Trees**// BinarySearchTree implementations publicboolean contains(Comparable data) { if (root == null) returnfalse; elsereturn root.contains(); } publicvoid add(Comparable data) { if (root == null) root = new Node(data); else root.add(data); } publicvoid delete(Comparable data) { ... } RHS – SWC**Binary Search Trees**public boolean contains(Comparable v) { if (data.compareTo(v) == 0) return true; Node next; if (data.compareTo(v) < 0) next = left; else next = right; if (next == null) returnfalse; else return (next.contains()); } RHS – SWC**Binary Search Trees**• We can search a Binary Search Tree in O(log(n)), which is fast • However, the condition for this ability is that the tree is always ”sorted”, i.e. obeys the ordering rules • Adding or deleting an element must preserve this ordering! RHS – SWC**Binary Search Trees**• Adding a new element E with value v is done using a recursive algorithm • Set current node N = root node • If N = null, replace it with E, else • If value(N.data) = v, we are done, else • If value(N.data) < v, set N = left child • If value(N.data) > v, set N = right child • Go to 2 RHS – SWC**Binary Search Trees**public void add(Comparable v) { if (data.compareTo(v) < 0) { if (left == null) left = new Node(v); else left.add(v); } elseif (data.compareTo(v) > 0) { if (right == null) right = new Node(v); else right.add(v); } } RHS – SWC**Binary Search Trees**• Deletion is actually the hardest part • What happens to the children of some deleted node N? • We must handle the cases where N has 0, 1 or 2 children • 0 children: Easy. Just find N and delete it. Parent reference (if any) to N must be set to null RHS – SWC**Binary Search Trees**N After Before RHS – SWC**Binary Search Trees**• 1 child: • Fairly easy. Find N and delete it. Parent refe-rence to N must be rerouted to the child of N • Note that if N is the root node, then the child of N becomes the new root node! RHS – SWC**Binary Search Trees**N C Note that C may have children itself… C After Before RHS – SWC**Binary Search Trees**• 2 children: • Complicated… Idea is to move the node with the next larger value in the tree up to take the position of N • Next larger value is found as the leftmost node in the right subtree of N • Keep going left in that subtree, until a node with no left child is found. Call this node L • Replace N with L RHS – SWC**Binary Search Trees**• Replace N with L • Copy data from L into N (not links!) • Delete original L, following the procedure for deleting a node with zero or a single child (L cannot have a left child) • These operations will preserve the ordering properties of the tree RHS – SWC**Tree Traversal**• The fact that a Binary Search Tree is ordered, make certain tasks quite easy • For instance, printing out the content of the tree in sorted order RHS – SWC**Tree Traversal**• Printing out a tree in sorted order: • Print out the left subtree • Print out data in the root node • Print out the right subtree • Again, a highly recursive algorithm… RHS – SWC**Tree Traversal**public void printNodes() // Node class { if (left != null) left.printNodes(); System.out.print(data + ” ”); if (right != null) right.printNodes(); } RHS – SWC**Tree Traversal**// BinarySearchTree class public void printTree() { if (root != null) root.printNodes(); } RHS – SWC**Tree Traversal**5 2 7 1 4 6 8 3 RHS – SWC**Tree Traversal**• This is known as in-order tree traversal: • Apply operation to left subtree • Apply basic operation to root • Apply operation to right subtree RHS – SWC**Tree Traversal**• We also have pre-order tree traversal: • Apply basic operation to root • Apply operation to left subtree • Apply operation to right subtree RHS – SWC**Tree Traversal**1 2 6 3 4 7 8 5 RHS – SWC**Tree Traversal**• And finally post-order tree traversal: • Apply operation to left subtree • Apply operation to right subtree • Apply basic operation to root RHS – SWC**Tree Traversal**8 4 7 1 3 5 6 2 RHS – SWC**Tree Traversal**• What tree traversal method to use depends entirely on your application • In-order outputs the content of the tree in sorted order • Pre- and post-order do not, but are used for other types of algorithms RHS – SWC**Choosing a proper container**• We have now learned about many types of containers for data • Which one is best…? • It depends… • Usage scenarios • Data types RHS – SWC**Choosing a proper container**• Issues in choosing a proper container • How do you access the elements? • Does element order matter? • Which operations must be fast? • Choosing between hash tables and trees (when using sets and maps) • Should I supply a comparator (when using trees)? RHS – SWC**Choosing a proper container**• How do you access the elements? • If you need access by a key, you should use a map • If you need access by an index, you should use an array or array list • If you only need to check if an element is already present in your container, you can use a set RHS – SWC**Choosing a proper container**• Does element order matter? • If elements should remain sorted, use a TreeSet • If the order of insertion should be preserved, use a linked list, array or array list • If it does not matter, let other criteria decide your choice RHS – SWC**Choosing a proper container**• Which operations must be fast? • Add and remove at the end of the container, use a linked list • Looking up a value quickly, use a set or map • If it does not matter, let other criteria decide your choice RHS – SWC**Choosing a proper container**• Choosing between hash tables and trees (when using sets and maps) • If your elements/keys are strings, use a hash table • If your elements/keys are defined by yourself, define proper hashCode and equals methods and use hash tables • If your elements/keys are defined by someone else, use hash tables if the hashCode and equals methods are properly defined, otherwise use trees RHS – SWC**Choosing a proper container**• Should I supply a comparator (when using trees)? • If the data type in your tree implements the Comparable interface properly, then no need for further action • If not, you can still use a tree anyway, by supplying a class that implements the Comparator interface, that can compare objects of the type used in the tree RHS – SWC