Presentation is loading. Please wait.

Presentation is loading. Please wait.

Computer Science 112 Fundamentals of Programming II Binary Search Trees.

Similar presentations


Presentation on theme: "Computer Science 112 Fundamentals of Programming II Binary Search Trees."— Presentation transcript:

1 Computer Science 112 Fundamentals of Programming II Binary Search Trees

2 Recursive Binary Search def index(target, sortedList): def recurse(first, last): if first > last: return -1 # target not there else: mid = (first + last) // 2 # compute midpoint if sortedList[mid] == target: return mid # found target elif sortedList[mid] > target: return recurse(first, mid – 1) # go left else: return recurse(mid + 1, last) # go right return recurse(0, len(sortedList) – 1)

3 Call Tree for Binary Search 34415663728995 0 1 2 3 4 5 6

4 Call Tree for Binary Search 34415663728995 0 1 2 3 4 5 6 344156 0 1 2 728995 4 5 6

5 Call Tree for Binary Search 34415663728995 0 1 2 3 4 5 6 344156 0 1 2 728995 4 5 6 3456 0 2 7295 4 6

6 Binary Search Tree (BST) 63 41 89 3456 7295

7 Binary Search Tree (BST) Ordering principle: –Each item in the left subtree is less than the item in the parent –Each item in the right subtree is greater than the item in the parent

8 contains(target, node) If the node is None Return False Else if node.data equals the target Return True Else if the target is greater than the data Return contains(target, node.right) Else Return contains(target, node.left) Recursive Search of a BST Node

9 t.isEmpty()Returns True if empty, False otherwise len(t)Returns the number of items in the tree str(t)Returns a string representation iter(t)Supports a for loop, visiting in preorder item in tTrue if item is in tree, False otherwise t1 + t2Returns a new tree with items in t1 and t2 t1 == t2Equality test for two trees t.add(item)Adds item to the tree t.remove(item)Removes the given item The precondition of remove is that the item is in the tree. Minimal Set of BST Operations

10 t.preorder()Returns an iterator for preorder traversal t.inorder()Returns an iterator for inorder traversal t.postorder()Returns an iterator for postorder traversal t.levelorder()Returns an iterator for levelorder traversal t.height()Returns the number of links from the root to the deepest leaf t.isBalanced()Returns True if t.height() < 2 * log 2 (len(t) + 1) - 1 or False otherwise t.rebalance()Rearranges the nodes to ensure that t.height() <= log 2 (len(t) + 1) Tree-Specific Operations

11 tree = LinkedBST() tree.add("D") tree.add("B") tree.add("A") tree.add("C") tree.add("F") tree.add("E") tree.add("G") print(tree) print("F" in tree) for item in tree: print(item) for item in tree.inorder(): print(item) for item in tree.postorder(): print(item) for item in tree.levelorder(): print(item) for ch in ('A', 'B', 'C', 'D', 'E', 'F', 'G'): print(tree.remove(ch)) Using a Binary Search Tree

12 from abstractcollection import AbstractCollection from bstnode import BSTNode class LinkedBST(AbstractCollection): def __init__(self, sourceCollection = None): self._root = None AbstractCollection.__init__(self, sourceCollection) # Tree methods go here The LinkedBST Class

13 def __contains__(self, target): """Returns True if target is found or False otherwise.""” def recurse(node): if node is None: return False elif node.data == target: return True elif node.data > target: return recurse(node.left) else: return recurse(node.right) return recurse(self._root) Method contains Several operations call nested helper functions to recurse on nodes

14 def __contains__(self, target): """Returns True if target is found or False otherwise.""” def recurse(node): return node != None and / (node.data == target or / (node.data > target and recurse(node.left)) or / recurse(node.right)) return recurse(self._root) Method contains Alternatively, for the logically intoxicated...

15 def preorder(self): """Supports a preorder traversal on a view of self.""" lyst = list() def recurse(node): if node != None: lyst.append(node.data) recurse(node.left) recurse(node.right) recurse(self._root) return iter(lyst) Preorder Traversal A traversal builds and returns a list of items in the order in which they were visited

16 def __iter__(self): """Supports a preorder traversal on a view of self.""" return self.preorder() iter – First Attempt The iterator captures a preorder traversal However, this implementation would incur linear running time and linear growth of memory before the caller ever accesses an item

17 If the tree is not empty Create a new stack Push the root node onto the stack While the stack is not empty Pop the top node and yield its data If the node’s right subtree is not empty Push the right subtree onto the stack If the node’s left subtree is not empty Push the left subtree onto the stack iter – Second Attempt Visits the nodes in preorder, yielding the datum in each node What is the running time and growth of memory?

18 B F A D G Adding Items to a BST New items are always added to the frontier of the tree, as leaf nodes

19 Case 1: The Tree is Empty Set the root to a new node containing the item

20 Case 2: The Tree Is Not Empty Search for the proper place for the new node B F A D G E

21 Case 2: The Tree Is Not Empty Search for the proper place for the new node B F A D G E

22 Case 2: The Tree Is Not Empty Search for the proper place for the new node B F A D G E

23 def add(self, item): """Adds item to self.""" # Tree is empty, so new item goes at the root if self.isEmpty(): self._root = BSTNode(item) # Otherwise, search for the item's spot else: recurse(self._root) self._size += 1 Method add Define a helper function recurse to perform the search for the new item’s place in a non-empty tree

24 def add(self, item): """Adds item to self.""" def recurse(node): # New item is less, go left until spot is found if item < node.data: if node.left is None: node.left = BSTNode(item) else: recurse(node.left) # New item is >=, go right until spot is found elif node.right is None: node.right = BSTNode(item) else: recurse(node.right) # Tree is empty, so new item goes at the root if self.isEmpty(): self._root = BSTNode(item) # Otherwise, search for the item's spot else: recurse(self._root) self._size += 1 Method add

25 def __str__(self): def recurse(node, level): s = "" if node != None: s += recurse(node.right, level + 1) s += "| " * level s += str(node.data) + "\n" s += recurse(node.left, level + 1) return s return recurse(self._root, 0) Method str Displays the tree rotated 90  counterclockwise

26 tree = LinkedBST() print(">>>>Items in advantageous order:") tree.add("E") tree.add("C") tree.add("D") tree.add("A") tree.add("H") tree.add("F") tree.add("K") print(tree) Adding Items in Best Order

27 print(">>>>Items in worst order:") tree = LinkedBST() for i in range(1, 9): tree.add(i) print(tree) Adding Items in Worst Order

28 print(">>>>Items in random order:") tree = LinkedBST() for i in range(7): tree.add(randomString()) print(tree) Adding Items in Random Order

29 Performance FDCABEGABCDEFG Worst Best

30 The Shape of the Tree As the tree becomes linear, searches and insertions degrade to linear A BST can be rebalanced in linear time Alternatively, a BST can be set up to maintain its balance during insertions

31 For Friday Parsing Expressions with Recursive Descent


Download ppt "Computer Science 112 Fundamentals of Programming II Binary Search Trees."

Similar presentations


Ads by Google