390 likes | 634 Views
Binary Trees and Binary Search Trees. Based on Dale & Co: Object-Oriented Data Structures using C++ (graphics). Binary Tree. A binary tree is a structure in which: Each node can have at most two children, and in which a unique path exists from the root to every other node.
E N D
Binary Trees andBinary Search Trees Based on Dale & Co: Object-Oriented Data Structures using C++ (graphics)
Binary Tree A binary tree is a structure in which: Each node can have at most two children, and in which a unique path exists from the root to every other node. The two children of a node are called the left child and the right child,if they exist.
A Binary Tree V Q L T A E K S
How many leaf nodes? V Q L T A E K S
How many descendants of Q? V Q L T A E K S
V Q L T A E K S How many ancestors of K?
A Binary Tree with Tree Nodes V Q L T E A K S
Binary Trees • You can write a class that represents each node in a binary tree • Called BinaryTreeNode • Instance variables of the class BinaryTreeNode • info: stores the information part of the node • lLink: points to the root node of the left subtree • rLink: points to the root node of the right subtree
Tree Traversals • Insertion, deletion, and lookup (and other) operations require that the binary tree be traversed • Commonly used traversals • Inorder traversal • Preorder traversal • Postorder traversal
Inorder (tree): LeftNodeRight • Binary tree is traversed as follows: • Traverse left subtree • Visit node • Traverse right subtree private void inorder(BinaryTreeNode<T> t){ if (t != null) { inorder(t.lLink); System.out.print(t.info + “ “); inorder(t.rLink); } } To print in alphabetical order
Postorder (tree): LeftRightNode • Binary tree is traversed as follows: • Traverse left subtree • Traverse right subtree • Visit node private void postorder(BinaryTreeNode<T> t){ if (t != null){ postorder(t.lLink); postorder(t.rLink); System.out.print(t.info + “ “); } } Visits leaves first (good for deletion)
Preorder (tree): NodeLeftRight • Binary tree is traversed as follows: • Visit node • Traverse left subtree • Traverse right subtree private void preorder(BinaryTreeNode<T> t){ if (t != null) { System.out.print(t.info + “ “); preorder(t.lLink); preorder(t.rLink); } } Useful with binary trees(not BST)
Binary Search Trees (BST) • To search for an item in a normal binary tree, you must traverse entire tree until item is found • Search process will be very slow • Similar to searching in an arbitrary linked list • Binary search tree • Data in each node is • Larger than the data in its left child • Smaller than the data in its right child
So, a Binary Search Tree (BST) is . . . A special kind of binary tree in which: 1. Each node contains a distinct data value, 2. The key values in the tree can be compared using “greater than” and “less than”, and 3. The key value of each node in the tree is less than every key value in its right subtree, and greater than every key value in its left subtree.
‘J’ The shape of a binary search tree . . . Depends on its key values and their order of insertion. Insert the elements ‘J’ ‘E’ ‘F’ ‘T’ ‘A’ in that order. The first value to be inserted is put into the root node.
‘J’ ‘E’ Inserting ‘E’ into the BST Thereafter, each value to be inserted begins by comparing itself to the value in the root node, moving left it is less, or moving right if it is greater. This continues at each level until it can be inserted as a new leaf.
‘J’ ‘E’ ‘F’ Inserting ‘F’ into the BST Begin by comparing ‘F’ to the value in the root node, moving left it is less, or moving right if it is greater. This continues until it can be inserted as a leaf.
‘J’ ‘T’ ‘E’ ‘F’ Inserting ‘T’ into the BST Begin by comparing ‘T’ to the value in the root node, moving left it is less, or moving right if it is greater. This continues until it can be inserted as a leaf.
‘J’ ‘T’ ‘E’ ‘A’ ‘F’ Inserting ‘A’ into the BST Begin by comparing ‘A’ to the value in the root node, moving left it is less, or moving right if it is greater. This continues until it can be inserted as a leaf.
‘A’ What binary search tree . . . is obtained by inserting the elements ‘A’ ‘E’ ‘F’ ‘J’ ‘T’ in that order?
‘A’ ‘E’ ‘F’ ‘J’ ‘T’ Binary search tree . . . obtained by inserting the elements ‘A’ ‘E’ ‘F’ ‘J’ ‘T’ in that order.
‘J’ Another binary search tree ‘T’ ‘E’ ‘A’ ‘H’ ‘M’ ‘P’ ‘K’ Add nodes containing these values in this order: ‘D’ ‘B’ ‘L’ ‘Q’ ‘S’ ‘V’ ‘Z’
‘D’ ‘Z’ ‘K’ ‘B’ ‘L’ ‘Q’ ‘S’ Is ‘F’ in the binary search tree? ‘J’ ‘T’ ‘E’ ‘A’ ‘V’ ‘M’ ‘H’ ‘P’
Tree Recursion Method countNodes (pseudocode): if tree is null return 0 else return countNodes(Left(tree)) + countNodes(Right(tree)) + 1
The Search Operation public boolean search(T item) { return recSearch(root, item); } //helper: recursive method called by search public boolean recSearch(BinaryTreeNode<T> tree, T item) { if(tree == null) return false; else { Comparable<T> temp = (Comparable<T>) tree.info; if (temp.compareTo(item) == 0) return true; else if (temp.compareTo(item) > 0) return recSearch(tree.lLink, item); else return recSearch(tree.rLink, item); } }
The Insert Operation • Important: A new node is always inserted into its appropriate position in the binary search tree as a leaf.
The Insert Operation public void insert(T item) { root = recInsert(root, item); } //helper: recursive method called by insert public BinaryTreeNode<T> recInsert(BinaryTreeNode<T> tree, T item) { if(tree == null) { //create new node tree = new BinaryTreeNode<T>(item); } else { Comparable<T> temp = (Comparable<T>) tree.info; if (temp.compareTo(item) == 0) { System.err.print("Already in - no duplicates."); return null; } else if (temp.compareTo(item) > 0) tree.lLink = recInsert(tree.lLink, item); else tree.rLink = recInsert(tree.rLink, item); } return tree; }
The Delete Operation • The delete operation has 3 cases • Node to be deleted is a leaf • Node to be deleted has 1 child (left OR right) • Node to be deleted has 2 children (nonempty left and right subtrees)
The Delete Operation Base Case: If item's key matches Info(tree), delete node General Case: If item < Info(tree), delete(Left(tree), item); else delete(Right(tree), item).
Code for Recursive Delete public void delete(T item) { root = recDelete(root, item); } //helper: recursive method called by delete public BinaryTreeNode<T> recDelete(BinaryTreeNode<T> tree, T item) { if(tree == null){ //empty tree System.err.println("Cannot delete from an empty tree."); return null; } else { Comparable<T> temp = (Comparable<T>) tree.info; if (temp.compareTo(item) > 0) tree.lLink = recDelete(tree.lLink, item); else if(temp.compareTo(item) < 0) tree.rLink = recDelete(tree.rLink, item); else if(tree.lLink != null && tree.rLink != null) {// 2 children tree.info = findMin(tree.rLink).info; //tree.info = findMax(tree.lLink).info; tree.rLink = removeMin(tree.rLink); } else if(root.lLink != null) //1 left child tree = tree.lLink; else if(root.rLink != null) //1 right child tree = tree.rLink; return tree; } }
Code for Recursive Delete //helper: method called by recDelete protected BinaryTreeNode<T> findMin(BinaryTreeNode<T> tree) { if(tree != null) while(tree.lLink != null) tree = tree.lLink; return tree; } //helper: method called by recDelete protected BinaryTreeNode<T> removeMin(BinaryTreeNode<T> tree) { if(tree == null){ //empty tree System.err.println("Cannot delete from an empty tree."); return null; } else if(tree.lLink != null) { tree.lLink = removeMin(tree.lLink); return tree; } else return tree.rLink; }