Finite-State Machines, Part 2
Total Page:16
File Type:pdf, Size:1020Kb
Binary Search Trees Insertion Let’s look at the code for inserting an item into a linked list. public void add(Comparable obj) { Node newNode = new Node(); newNode.data = obj newNode.left = null newNode.right = null if (root == null) root = newNode; else root.addNode(newNode); }
OK, this code punts most of the work to a method of what class? Node Let’s take a look at that method. public void addNode(Node newNode) { int comp = newNode.data.compareTo(data); if (comp < 0) { if (left == null) left = newNode; else left.addNode(newNode); } if (comp > 0) { if (right == null) right = newNode; else right.addNode(newNode); } }
Let’s practice by inserting these nodes into a tree: 5, 3, 7, 2, 4, 6, 8, 1, 9 What kind of tree would we get if they came in this order: 9, 8, 7, 6, 5, 4, 3, 2, 1?
How many comparisons, on average, does it take to locate a node in the first tree? 1 + 2 x 2 + 3 x 4 + 4 x 2 = 25. 25/9 = 2.7777… O(log n) Lecture 24 Programming Concepts—Java 1 In the second tree? 1 + 2 + 3 + … + 9 = 45. 45/9 = 5 O(n) Deletion Now let’s consider how to delete a node from a binary tree. There are three possibilities. Let’s define victim = the node to be deleted. The victim has no children. The victim has one child. The victim has two children. The first case is easy; just set the parent’s link to null The second case is not much harder; set the parent’s link (that pointed to the victim) to point to the victim’s child. The third case is the hard one. In this case, we replace the data in the victim node with the next larger value in the tree. Another way of describing this element is the smallest value in the right subtree of the victim. Can you give an algorithm for finding this element? 1. Start from the victim, and look in the right subtree. 2. Keep following left links until a null left link is encountered.
Take the node with a null left link; we’ll call it the uplifted node, and copy its value to the victim node.
What else do we have to do to finish the deletion? We need to make some link point to the (right) child of the uplifted node. Which link is that? The left link of the parent of the uplifted node. Examples: What happens if we delete 9 from the tree below? 3? 7?
CSC 216 Lecture Notes Fall 2006 2 7
6 9
3 8 11
1 5 10
Now let’s consider the first tree that we used for insertion practice: What happens if we delete 5 7? 8 gets moved up to replace 3 7 7, but unfortunately its left link is redirected (left link 2 4 6 8 was still pointing to a live node). Which link should be set to 1 9 point to the child of the uplifted node? The right link (of the parent of the uplifted node). This is actually a special case in the algorithm. Can you describe when the right link should be redirected, instead of the left link? When the uplifted node is the child of the victim.
Let’s modify the algorithm to account for this. But first we need to look at the algorithm … public void remove(Comparable obj) { // Find node to be removed
Lecture 24 Programming Concepts—Java 3 Node victim = root; Node parent = null; boolean found = false;
while (!found && victim != null) { int d = victim.data.compareTo(obj); if (d == 0) found = true; else { parent = victim; if (d > 0) victim = victim.left; else victim = victim.right; } }
if (!found) return; // or throw new(NoSuchElementException);
// victim contains obj
// If 1 of the children is empty, use the other if (victim.left == null || victim.right == null) { Node newChild = null; if (victim.left == null) newChild = victim.right; if (victim.right == null) newChild = victim.left;
if (parent == null) // Found in root root = newChild; else if (parent.left == victim) parent.left = newChild; else parent.right = newChild; return; }
// Neither subtree is empty
CSC 216 Lecture Notes Fall 2006 4 // Find smallest element of the right subtree Node smallestParent = victim; Node smallest = victim.right; while (smallest.left != null) { smallestParent = smallest; smallest = smallest.left; }
// smallest contains smallest child in right // subtree // Move contents, unlink child victim.data = smallest.data; if (smallestParent == victim) smallestParent.right = smallest.right; else smallestParent.left = smallest.right; }
Question: How would we modify this method to throw an exception when an element is not found?
Now let’s use the revised algorithm to remove 5, 3, 6, 4, and 8 from the binary tree. Raise your hand when you think you have it. Traversal Given the rule for insertion into a binary tree: If value is less than the current node’s, move to the left subtree. If there is no left subtree, insert it here. If value is greater than the current node’s, move to the right subtree. If there is no right subtree, insert it here. how should we traverse that tree? Hint: There are three things to do: Visit the current node itself; visit the left
Lecture 24 Programming Concepts—Java 5 subtree, visit the right subtree. What order do we do them in? Visit the left subtree; visit the node itself; visit the right subtree. Here is a traversal routine: public void printNodes() { if (left != null) left.printNodes(); System.out.print(data + “ “); if (right != null) right.printNodes(); } This is called an inorder traversal. There are two other kinds. Preorder: Visit the root; visit the left subtree; visit the right subtree. Postorder: Visit the left subtree; visit the right subtree; visit the root. What would a preorder traversal of the tree below yield?
5
3 7
2 4 6 8
1 9
5, 3, 2, 1, 4, 7, 6, 8, 9
CSC 216 Lecture Notes Fall 2006 6