Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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