430 likes | 551 Views
Binary Trees. 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. 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