Week 7 - Friday
What did we talk about last time? Trees in general Binary search trees
Infix to Postfix Converter
public class Tree { private static class Node { public int key; public Object value; public Node left; public Node right; } private Node root = null; … } The book uses a generic approach, with keys of type Key and values of type Value. The algorithms we'll use are the same, but I use int keys to simplify comparison.
Almost all the methods we call on trees will be recursive Each will take a Node reference to the root of the current subtree Because the root is private, assume that every recursive method is called by a public, non-recursive proxy method: public Type doSomething() calls private static Type doSomething( Node root )
private static Node add(Node node, int key, Object value) Proxy: public void add(int key, Object value) { root = add( root, key, value ); } Find where the node should be. If there is already a matching key, do nothing. Otherwise, put a new node at the null location. Note: This can cause an unbalanced tree.
Let h be the height of a binary tree A perfect binary tree has 2 h+1 – 1 nodes Alternatively, a perfect binary tree has 2L – 1 nodes, where L is the number of leaves A complete binary tree has between 2 h and 2 h+1 – 1 (exclusive) nodes A binary tree with n nodes has n + 1 null links
Unbalanced BST: O(n) find O(n) insert O(n) delete Balanced BST: O(log n) find O(log n) insert O(log n) delete
Visiting every node in a tree is called a traversal There are three traversals that we are interested in today: Preorder Postorder Inorder We'll get to level order traversal in the future
Preorder: Process the node, then recursively process its left subtree, finally recursively process its right subtree NLR Postorder: Recursively process the left subtree, recursively process the right subtree, and finally process the node LRN Inorder: Recursively process the left subtree, process the node, and finally recursively process the right subtree LNR
public class Tree { private static class Node { public int key; public Object value; public Node left; public Node right; } private Node root = null; … } The book uses a generic approach, with keys of type Key and values of type Value. The algorithms we'll use are the same, but I use int keys to simplify comparison.
private static void preorder( Node node ) Proxy: public void preorder() { preorder( root ); } Just print out each node (or a dot). Real traversals will actually do something at each node.
private static void inorder( Node node ) Proxy: public void inorder() { inorder( root ); } Just print out each node (or a dot). Real traversals will actually do something at each node.
private static void postorder( Node node ) Proxy: public void postorder() { postorder( root ); } Just print out each node (or a dot). Real traversals will actually do something at each node.
We can take the idea of an inorder traversal and use it to store a range of values into a queue We want to store all values greater than or equal to the min and less than the max private static void getRange( Node node, Queue queue, int min, int max ) Proxy: public Queue getRange(int min, int max){ Queue queue = new ArrayDeque (); getRange( root, queue, min, max ); return queue; }
private static Node delete(Node node, int key) Proxy: public void delete(int key) { root = delete( root, key ); } 1. Find the node 2. Find its replacement (smallest right child or largest left child) 3. Swap out the replacement We may need some subroutines: private static Node smallest(Node node, Node parent) private static Node largest(Node node, Node parent) Note: This can cause an unbalanced tree.
Finish delete Breadth first traversal Balancing binary search trees 2-3 search trees Red-black trees
Finish Project 2 Due tonight by midnight Read section 3.3 Start Assignment 4 Due next Friday Office hours from 3:30-5pm canceled today due to travel