Binary Trees The Abstract Data Type Tree An ADT tree root node internal Has one entry point, the root nodes Each node is either a leaf or an internal node An internal node has 1 or more children, nodes that can be reached directly from that internal node. The internal node is said to be the parent of its child nodes leaf nodes 2 Properties of Trees and Nodes siblings: two nodes that have the same parent edge edge: the link from one node to another path length: the number of edges that must be traversed to get from one node to another root siblings path length from root to this node is 3 3 More Properties of Trees depth: the path length from the root of the tree to this node height of a node: The maximum distance (path length) of any leaf from this node a leaf has a height of 0 the height of a tree is the height of the root of that tree descendants: any nodes that can be reached via 1 or more edges from this node ancestors: any nodes for which this node is a descendant 4 Binary Trees There are many variations on trees but we will focus on binary trees binary tree: each node has at most two children the possible children are usually referred to as the left child and the right child parent left child right child 5 Full Binary Tree Full binary tree: a binary tree in which each node has exactly 2 or 0 children What is the maximum height of a full binary tree with 11 nodes? 6 Complete Binary Tree complete binary tree: a binary tree in which every level, except possibly the deepest is completely filled. At depth n, the height of the tree, all nodes are as far left as possible A. Where would the next node go to maintain a complete tree? B. What is the height of a complete binary tree that contains N nodes? 7 Perfect Binary Tree perfect binary tree: a binary tree with all leaf nodes at the same depth. All internal nodes have exactly two children. a perfect binary tree has the maximum number of nodes for a given height a perfect binary tree has (2(h+1) - 1) nodes where h is the height of the tree height = 0 -> 1 node height = 1 -> 3 nodes height = 2 -> 7 nodes height = 3 -> 15 nodes 8 Balanced binary tree a a b d h i c e f b c g j A balanced binary tree d e f g h i j An unbalanced binary tree A binary tree is balanced if every level above the lowest is “full” (contains 2n nodes) In most applications, a reasonably balanced binary tree is desirable 9 Sorted binary trees A binary tree is sorted if every node in the tree is larger than (or equal to) its left descendants, and smaller than (or equal to) its right descendants Equal nodes can go either on the left or the right (but it has to be consistent) 10 8 4 15 12 20 17 10 Binary search in a sorted array Look at array location (lo + hi)/2 Searching for 5: (0+6)/2 = 3 hi = 2; (0 + 2)/2 = 1 Using a binary search tree lo = 2; (2+2)/2=2 7 3 0 2 1 2 3 5 3 4 5 13 6 7 11 13 17 2 5 11 17 11 Tree traversals A binary tree is defined recursively: it consists of a root, a left subtree, and a right subtree To traverse (or walk) the binary tree is to visit each node in the binary tree exactly once Tree traversals are naturally recursive Since a binary tree has three “parts,” there are six possible ways to traverse the binary tree: root, left, right (pre-order) left, root, right (in-order) left, right, root (post-order) root, right, left right, root, left right, left, root 12 class BinaryTree class BinaryTree { int key; BinaryTree leftChild; BinaryTree rightChild; // Other methods… } A constructor for a binary tree should have three parameters, corresponding to the three fields 13 Preorder traversal In preorder, the root is visited first Here’s a preorder traversal to print out all the elements in the binary tree: public void preorderPrint(BinaryTree bt) { if (bt == null) return; System.out.println(bt.key); preorderPrint(bt.leftChild); preorderPrint(bt.rightChild); } 14 Inorder traversal In inorder, the root is visited in the middle Here’s an inorder traversal to print out all the elements in the binary tree: public void inorderPrint(BinaryTree bt) { if (bt == null) return; inorderPrint(bt.leftChild); System.out.println(bt.key); inorderPrint(bt.rightChild); } 15 Postorder traversal In postorder, the root is visited last Here’s a postorder traversal to print out all the elements in the binary tree: public void postorderPrint(BinaryTree bt) { if (bt == null) return; postorderPrint(bt.leftChild); postorderPrint(bt.rightChild); System.out.println(bt.key); } 16 Tree traversals using “flags” The order in which the nodes are visited during a tree traversal can be easily determined by imagining there is a “flag” attached to each node, as follows: preorder inorder postorder To traverse the tree, collect the flags: A B D C E A A F ABDECFG B G D B C E F DBEAFCG G D C E F G DEBFGCA 17 Copying a binary tree In postorder, the root is visited last Here’s a postorder traversal to make a complete copy of a given binary tree: public static BinaryTree copyTree(BinaryTree bt) { if (bt == null) return null; BinaryTree left = copyTree(bt.leftChild); BinaryTree right = copyTree(bt.rightChild); return new BinaryTree(bt.key, left, right); } 18 Other traversals The other traversals are the reverse of these three standard ones That is, the right subtree is traversed before the left subtree is traversed Reverse preorder: root, right subtree, left subtree Reverse inorder: right subtree, root, left subtree Reverse postorder: right subtree, left subtree, root 19 Binary Search Tree (BST) Stores keys in the nodes in a way so that searching, insertion and deletion can be done efficiently. Binary search tree property For every node X, all the keys in its left subtree are smaller than the key value in X, and all the keys in its right subtree are larger than the key value in X 20 BST A binary search tree Not a binary search tree 21 BST Two binary search trees representing the same set: Average depth of a node is O(log N); maximum depth of a node is O(N) 22 BST Implementation class BST { Comparable BST BST key; leftChild; rightChild; // add methods… } 23 Searching BST If we are searching for 15, then we are done. If we are searching for a key < 15, then we should search in the left subtree. If we are searching for a key > 15, then we should search in the right subtree. 24 Searching for 9 … 25 Searching (find) Implementation Find X: return a reference to the node that has key X, or NULL if there is no such node public BST find(Comparable key, BST bst) { if (bst == NULL) return NULL; else if (key.compareTo(bst.key)==-1) return find(key,bst.leftchild); else if (key.compareTo(bst.key)==1) return find(key,bst.rightchild); else return bst; } Time complexity O(height of the tree) 26 Inorder traversal of BST Print out all the keys in sorted order Inorder: 2, 3, 4, 6, 7, 9, 13, 15, 17, 18, 20 27 findMin/ findMax Return the node containing the smallest element in the tree Start at the root and go left as long as there is a left child. The stopping point is the smallest element public BST findMin(BST bst) { if (bst == NULL) return NULL; if (bst.leftchild == NULL) retun bst; return findMin(bst.leftchild); } Similarly for findMax Time complexity = O(height of the tree) 28 insert Proceed down the tree as you would with a find If X is found, do nothing (or update something) Otherwise, insert X at the last spot on the path traversed Time complexity = O(height of the tree) 29 delete When we delete a node, we need to consider how we take care of the children of the deleted node. This has to be done such that the property of the search tree is maintained. 30 delete Three cases: (1) the node is a leaf Delete it immediately (2) the node has one child Adjust a pointer from the parent to bypass that node Deletion of a node (4) with one child Before After 31 delete (3) the node has 2 children replace the key of that node with the minimum element at the right subtree delete the minimum element Has either no child or only right child because if it has a left child, that left child would be smaller and would have been chosen. So invoke case 1 or 2. Deletion of a node (2) with two children Before After Time complexity = O(height of the tree) 32