CS 106B Lecture 20: Binary Search Trees Wednesday, May 17, 2017

Slides:



Advertisements
Similar presentations
1 AVL-Trees (Adelson-Velskii & Landis, 1962) In normal search trees, the complexity of find, insert and delete operations in search trees is in the worst.
Advertisements

AVL Trees COL 106 Amit Kumar Shweta Agrawal Slide Courtesy : Douglas Wilhelm Harder, MMath, UWaterloo
Trees Types and Operations
AVL Tree Smt Genap Outline AVL Tree ◦ Definition ◦ Properties ◦ Operations Smt Genap
AVL Trees CS II – Fall /8/2010. Announcements HW#2 is posted – Uses AVL Trees, so you have to implement an AVL Tree class. Most of the code is provided.
Binary Trees, Binary Search Trees CMPS 2133 Spring 2008.
CS202 - Fundamental Structures of Computer Science II
Binary Trees, Binary Search Trees COMP171 Fall 2006.
AA Trees another alternative to AVL trees. Balanced Binary Search Trees A Binary Search Tree (BST) of N nodes is balanced if height is in O(log N) A balanced.
AVL-Trees (Part 1) COMP171. AVL Trees / Slide 2 * Data, a set of elements * Data structure, a structured set of elements, linear, tree, graph, … * Linear:
TCSS 342 AVL Trees v1.01 AVL Trees Motivation: we want to guarantee O(log n) running time on the find/insert/remove operations. Idea: keep the tree balanced.
AVL-Trees (Part 1: Single Rotations) Lecture COMP171 Fall 2006.
AVL Trees / Slide 1 Balanced Binary Search Tree  Worst case height of binary search tree: N-1  Insertion, deletion can be O(N) in the worst case  We.
1 BST Trees A binary search tree is a binary tree in which every node satisfies the following: the key of every node in the left subtree is.
BINARY SEARCH TREE. Binary Trees A binary tree is a tree in which no node can have more than two children. In this case we can keep direct links to the.
Binary Trees, Binary Search Trees RIZWAN REHMAN CENTRE FOR COMPUTER STUDIES DIBRUGARH UNIVERSITY.
CSIT 402 Data Structures II
1 Trees 4: AVL Trees Section 4.4. Motivation When building a binary search tree, what type of trees would we like? Example: 3, 5, 8, 20, 18, 13, 22 2.
Lec 15 Oct 18 Binary Search Trees (Chapter 5 of text)
Lecture 11COMPSCI.220.FS.T Balancing an AVLTree Two mirror-symmetric pairs of cases to rebalance the tree if after the insertion of a new key to.
Binary Search Trees (BSTs) 18 February Binary Search Tree (BST) An important special kind of binary tree is the BST Each node stores some information.
Data Structures AVL Trees.
Week 10 - Friday.  What did we talk about last time?  Graph representations  Adjacency matrix  Adjacency lists  Depth first search.
AVL Trees An AVL tree is a binary search tree with a balance condition. AVL is named for its inventors: Adel’son-Vel’skii and Landis AVL tree approximates.
AVL Trees / Slide 1 Height-balanced trees AVL trees height is no more than 2 log 2 n (n is the number of nodes) Proof based on a recurrence formula for.
Lecture 10COMPSCI.220.FS.T Binary Search Tree BST converts a static binary search into a dynamic binary search allowing to efficiently insert and.
1 Binary Search Trees  Average case and worst case Big O for –insertion –deletion –access  Balance is important. Unbalanced trees give worse than log.
Red-Black Trees an alternative to AVL trees. Balanced Binary Search Trees A Binary Search Tree (BST) of N nodes is balanced if height is in O(log N) A.
CE 221 Data Structures and Algorithms Chapter 4: Trees (AVL Trees) Text: Read Weiss, §4.4 1Izmir University of Economics.
COMP 53 – Week Fourteen Trees.
Lecture 15 Nov 3, 2013 Height-balanced BST Recall:
AA Trees.
Lec 13 Oct 17, 2011 AVL tree – height-balanced tree Other options:
BCA-II Data Structure Using C
Data Structures – LECTURE Balanced trees
Week 7 - Friday CS221.
Balancing Binary Search Trees
UNIT III TREES.
CSIT 402 Data Structures II
CS202 - Fundamental Structures of Computer Science II
CS202 - Fundamental Structures of Computer Science II
CS 201 Data Structures and Algorithms
CSE373: Data Structures & Algorithms Lecture 7: AVL Trees
Balanced Trees (AVL and RedBlack)
CSCS-200 Data Structures and Algorithms
Week 11 - Friday CS221.
CSE373: Data Structures & Algorithms Lecture 7: AVL Trees
Binary Trees, Binary Search Trees
Chapter 22 : Binary Trees, AVL Trees, and Priority Queues
Monday, April 16, 2018 Announcements… For Today…
original list {67, 33,49, 21, 25, 94} pass { } {67 94}
TCSS 342, Winter 2006 Lecture Notes
AVL Trees CENG 213 Data Structures.
CS202 - Fundamental Structures of Computer Science II
Balanced-Trees This presentation shows you the potential problem of unbalanced tree and show two way to fix it This lecture introduces heaps, which are.
CS202 - Fundamental Structures of Computer Science II
Balanced-Trees This presentation shows you the potential problem of unbalanced tree and show two way to fix it This lecture introduces heaps, which are.
Tree Rotations and AVL Trees
CSE 332: Data Abstractions AVL Trees
Binary Trees, Binary Search Trees
CE 221 Data Structures and Algorithms
Self-Balancing Search Trees
CS202 - Fundamental Structures of Computer Science II
AVL-Trees (Part 1).
BST Insert To insert an element, we essentially do a find( ). When we reach a NULL pointer, we create a new node there. void BST::insert(const Comp &
Lecture 10 Oct 1, 2012 Complete BST deletion Height-balanced BST
1 Lecture 13 CS2013.
Binary Trees, Binary Search Trees
CS202 - Fundamental Structures of Computer Science II
CS202 - Fundamental Structures of Computer Science II
Presentation transcript:

CS 106B Lecture 20: Binary Search Trees Wednesday, May 17, 2017 Programming Abstractions Spring 2017 Stanford University Computer Science Department Lecturer: Chris Gregg reading: Programming Abstractions in C++, Sections 16.1-16.3 (binary search trees), Chapter 15 (hashing)

Today's Topics Logistics Assignment 5 handout: not our best work…very sorry about that. Because of our mistakes, we have a gift… I will post a "Tiny Feedback questions and answers" page soon Binary Search Trees Definition Traversing Tree functions References to pointers Keeping Trees Balanced

Binary Search Trees Binary trees are frequently used in searching. Binary Search Trees (BSTs) have an invariant that says the following: For every node, X, all the items in its left subtree are smaller than X, and the items in the right tree are larger than X.

Binary Search Tree Not a Binary Search Tree Binary Search Trees Binary Search Tree Not a Binary Search Tree 6 2 8 4 1 3 6 2 8 1 4 3 7

Binary Search Trees Binary Search Trees (if built well) have an average depth on the order of log2(n): very nice! 6 2 8 4 1 3

Binary Search Trees In order to use binary search trees (BSTs), we must define and write a few methods for them (and they are all recursive!) 6 2 8 4 1 3 Easy methods: findMin() findMax() contains() add() Hard method: remove()

Binary Search Trees: findMin() Start at root, and go left until a node doesn’t have a left child. findMax(): Start at root, and go right until a node doesn’t have a right child. 6 2 8 4 1 3

Binary Search Trees: contains() Does tree T contain X? If T is empty, return false If T is X, return true Recursively call either T→left or T→right, depending on X’s relationship to T (smaller or larger). 6 2 8 4 1 3

Binary Search Trees: add(value) 6 2 8 4 1 3 Similar to contains() If T is empty, add at root Recursively call either T→left or T→right, depending on X’s relationship to T (smaller or larger). If node traversed to is NULL, add How do we add 5?

Binary Search Trees: remove(value) 6 2 8 4 1 3 Harder. Several possibilities. Search for node (like contains) If the node is a leaf, just delete (phew) If the node has one child, “bypass” (think linked-list removal) … How do we delete 4?

Binary Search Trees: remove(value) 6 2 8 If a node has two children: Replace with smallest data in the right subtree, and recursively delete that node (which is now empty). 1 5 3 4 Note: if the root holds the value to remove, it is a special case… How do we remove 2?

BSTs and Sets 6 Guess what? BSTs make a terrific container for a set Let's talk about Big O (average case) 2 8 1 5 findMin()? O(log n) findMax()? O(log n) 3 insert()? O(log n) 4 remove()? O(log n) Great! That said...what about worst case?

Using References to Pointers To insert into a binary search tree, we must update the left or right pointer of a node when we find the position where the new node must go. In principle, this means that we could either Perform arms-length recursion to determine if the child in the direction we will insert is NULL, or Pass a reference to a pointer to the parent as we recurse. The second choice above is the cleaner solution. 6 2 8 set.add(5) 1 4 insert here 3

Using References to Pointers node (reference) void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } root 6 2 8 1 4 insert here 3

Using References to Pointers node (reference) void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } root 6 2 8 1 4 insert here 3

Using References to Pointers void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } node (reference) root 6 2 8 1 4 insert here 3

Using References to Pointers void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node *&node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } node (reference) root 6 2 8 1 4 insert here 3

Using References to Pointers void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node *&node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node *&node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } node (reference) root 6 2 8 1 4 insert here 3

Using References to Pointers void StringSet::add(string s, Node *&node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node *&node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node *&node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } void StringSet::add(string s, Node* &node) { if (node == NULL) { node = new Node(s); count++; } else if (node->str > s) { add(s, node->left); } else if (node->str < s) { add(s, node->right); } node (reference) root 6 2 8 1 4 3 5

Balancing Trees 20 33 50 61 87 99 Insert the following into a BST: 20, 33, 50, 61, 87, 99 What kind of tree to we get? 33 50 We get a Linked List Tree, and O(n) behavior :( 61 What we want is a "balanced" tree (that is one nice thing about heaps -- they're always balanced!) 87 99

Balancing Trees Possible idea: require that the left and right subtrees in a BST have the same height.

Balancing Trees 20 87 50 33 61 99 3 14 18 7 2 But, bad balancing can also be problematic... This tree is balanced, but only at the root.

Balancing Trees: What we want Another balance condition could be to insist that every node must have left and right subtrees of the same height: too rigid to be useful: only perfectly balanced trees with 2k-1 nodes would satisfy the condition (even with the guarantee of small depth).

Balancing Trees: What we want 18 7 61 3 14 33 87 2 20 50 99 We are going to look at one balanced BST in particular, called an "AVL tree" You can play around with AVL trees here: https://www.cs.usfca.edu/~galles/visualization/AVLtree.html

AVL Trees An AVL tree (Adelson-Velskii and Landis) is a compromise. It is the same as a binary search tree, except that for every node, the height of the left and right subtrees can differ only by 1 (and an empty tree has a height of -1). 5 2 8 4 1 7 3 7 2 8 4 1 5 3 Not an AVL Tree AVL Tree

AVL Trees Height information is kept for each node, and the height is almost log N in practice. 5 2 8 4 1 7 3 When we insert into an AVL tree, we have to update the balancing information back up the tree We also have to maintain the AVL property — tricky! Think about inserting 6 into the tree: this would upset the balance at node 8.

AVL Trees: Rotation As it turns out, a simple modification of the tree, called rotation, can restore the AVL property. 5 2 8 4 1 7 3 After insertion, only nodes on the path from the insertion might have their balance altered, because only those nodes had their subtrees altered. We will re-balance as we follow the path up to the root updating balancing information.

AVL Trees: Rotation We will call the node to be balanced, 𝝰 5 2 8 4 1 7 3 Because any node has at most two children, and a height imbalance requires that 𝝰’s two subtrees’ heights differ by two, there can be four violation cases: An insertion into the left subtree of the left child of 𝝰. An insertion into the right subtree of the left child of 𝝰. An insertion into the left subtree of the right child of 𝝰. An insertion into the right subtree of the right child of 𝝰.

AVL Trees: Rotation 5 2 8 4 1 7 3 For “outside” cases (left-left, right- right), we can do a “single rotation” For “inside” cases (left-right, right, left), we have to do a more complex “double rotation.”

AVL Trees: Single Rotation k2 k1 X Y Z k2 violates the AVL property, as X has grown to be 2 levels deeper than Z. Y cannot be at the same level as X because k2 would have been out of balance before the insertion. We would like to move X up a level and Z down a level (fine, but not strictly necessary).

AVL Trees: Single Rotation k2 k1 X Y Z Visualization: Grab k1 and shake, letting gravity take hold. k1 is now the new root. In the original, k2 > k1, so k2 becomes the right child of k1. X and Z remain as the left and right children of k1 and k2, respectively. Y can be placed as k2’s left child and satisfies all ordering requirements.

AVL Trees: Single Rotation 5 5 2 8 2 7 1 4 7 1 4 6 3 6 3 Insertion of 6 breaks AVL property at 8 (not 5!), but is fixed with a single rotation (we “rotate 8 right” by grabbing 7 and hoisting it up)

AVL Trees: Single Rotation k2 k1 Z Y X It is a symmetric case for the right-subtree of the right child. k1 is unbalanced, so we “rotate k1 left” by hoisting k2)

AVL Trees: Single Rotation http://www.cs.usfca.edu/~galles/visualization/AVLtree.html Insert 3, 2, 1, 4, 5, 6, 7

AVL Trees: Single Rotation doesn’t work for right/left, left/right! AVL Trees: Double Rotation AVL Trees: Single Rotation doesn’t work for right/left, left/right! k2 k1 k1 k2 Z X Z X Y Y Subtree Y is too deep (unbalanced at k2), and the single rotation does not make it any less deep.

AVL Trees: Double Rotation AVL Trees: Double Rotation (can be thought of as one complex rotation or two simple single rotations) Y Z k1 k2 C B X D k3 A Instead of three subtrees, we can view the tree as four subtrees, connected by three nodes.

AVL Trees: Double Rotation k2 D k1 k3 C B A We can’t leave k2 as root, nor can we make k1 root (as shown before). So, k3 must become the root.

AVL Trees: Double Rotation k1 k2 k3 k1 k3 k2 A B C D A D B C Double rotation also fixes an insertion into the left subtree of the right child (k1 is unbalanced, so we first rotate k3 right, then we rotate k1 left)

AVL Trees: Double Rotation http://www.cs.usfca.edu/~galles/visualization/AVLtree.html Before: Insert 17, 12, 23, 9, 14, 19 Insert: 20

AVL Trees: Double Rotation http://www.cs.usfca.edu/~galles/visualization/AVLtree.html Before: Insert 20, 10, 30, 5, 25, 40, 35, 45 Insert: 34

AVL Trees: Rotation Practice http://www.cs.usfca.edu/~galles/visualization/AVLtree.html Before: Insert 30, 20, 10, 40, 50, 60, 70 Continuing: Insert 160, 150, 140, 130, 120, 110, 100, 80, 90

AVL Trees: How to Code Coding up AVL tree rotation is straightforward, but can be tricky. A recursive solution is easiest, but not too fast. However, clarity generally wins out in this case. To insert a new node into an AVL tree: Follow normal BST insertion. If the height of a subtree does not change, stop. If the height does change, do an appropriate single or double rotation, and update heights up the tree. One rotation will always suffice. Example code can be found here: http://www.sanfoundry.com/cpp-program-implement-avl-trees/

Other Balanced Tree Data Structures AA tree AVL tree Red-black tree Scapegoat tree Splay tree Treap

Coding up a StringSet struct Node { string str; Node *left; Node *right; // constructor for new Node Node(string s) { str = s; left = NULL; right = NULL; } }; class StringSet { ...

References and Advanced Reading http://www.openbookproject.net/thinkcs/python/english2e/ch21.html https://www.tutorialspoint.com/data_structures_algorithms/binary_search_tree.htm https://en.wikipedia.org/wiki/Binary_search_tree https://www.cise.ufl.edu/~nemo/cop3530/AVL-Tree-Rotations.pdf Advanced Reading: Tree (abstract data type), Wikipedia: http://en.wikipedia.org/wiki/Tree_(data_structure) Binary Trees, Wikipedia: http://en.wikipedia.org/wiki/Binary_tree Tree visualizations: http://vcg.informatik.uni-rostock.de/~hs162/treeposter/poster.html Wikipedia article on self-balancing trees (be sure to look at all the implementations): http://en.wikipedia.org/wiki/Self-balancing_binary_search_tree Red Black Trees: https://www.cs.auckland.ac.nz/software/AlgAnim/red_black.html YouTube AVL Trees: http://www.youtube.com/watch?v=YKt1kquKScY Wikipedia article on AVL Trees: http://en.wikipedia.org/wiki/AVL_tree Really amazing lecture on AVL Trees: https://www.youtube.com/watch?v=FNeL18KsWPc

Extra Slides

In-Order Traversal: It is called "in-order" for a reason! 6 2 7 Pseudocode: 1 5 base case: if current == NULL, return recurse left do something with current node recurse right 3 4

In-Order Traversal Example: printing 6 2 7 Current Node: 6 current not NULL recurse left 1 5 3 4 Output:

In-Order Traversal Example: printing 6 2 7 Current Node: 2 current not NULL recurse left 1 5 3 4 Output:

In-Order Traversal Example: printing 6 2 7 Current Node: 1 current not NULL recurse left 1 5 3 4 Output:

In-Order Traversal Example: printing 6 2 7 1 5 Current Node: NULL current NULL: return 3 4 Output:

In-Order Traversal Example: printing 6 2 7 Current Node: 1 current not NULL recurse left print "1" recurse right 1 5 3 4 Output: 1

In-Order Traversal Example: printing 6 2 7 1 5 Current Node: NULL current NULL: return 3 4 Output: 1

In-Order Traversal Example: printing 6 2 7 Current Node: 1 current not NULL recurse left print "1" recurse right (function ends) 1 5 3 4 Output: 1

In-Order Traversal Example: printing 6 2 7 Current Node: 2 current not NULL recurse left print "2" recurse right 1 5 3 4 Output: 1 2

In-Order Traversal Example: printing 6 2 7 Current Node: 5 current not NULL recurse left 1 5 3 4 Output: 1 2

In-Order Traversal Example: printing 6 2 7 Current Node: 3 current not NULL recurse left 1 5 3 4 Output: 1 2

In-Order Traversal Example: printing 6 2 7 1 5 Current Node: NULL 1. current NULL: return 3 4 Output: 1 2

In-Order Traversal Example: printing 6 2 7 Current Node: 3 current not NULL recurse left print "3" recurse right 1 5 3 4 Output: 1 2 3

In-Order Traversal Example: printing 6 2 7 Current Node: 4 current not NULL recurse left 1 5 3 4 Output: 1 2 3

In-Order Traversal Example: printing 6 2 7 1 5 Current Node: NULL current NULL, return 3 4 Output: 1 2 3

In-Order Traversal Example: printing 6 2 7 Current Node: 4 current not NULL recurse left print "4" recurse right 1 5 3 4 Output: 1 2 3 4

In-Order Traversal Example: printing 6 2 7 1 5 Current Node: NULL current NULL, return 3 4 Output: 1 2 3 4

In-Order Traversal Example: printing 6 2 7 Current Node: 4 current not NULL recurse left print "4" recurse right (function ends) 1 5 3 4 Output: 1 2 3 4

In-Order Traversal Example: printing 6 2 7 Current Node: 3 current not NULL recurse left print "3" recurse right (function ends) 1 5 3 4 Output: 1 2 3 4

In-Order Traversal Example: printing 6 2 7 Current Node: 5 current not NULL recurse left print "5" recurse right 1 5 3 4 Output: 1 2 3 4 5

In-Order Traversal Example: printing 6 2 7 1 5 Current Node: NULL current NULL, return 3 4 Output: 1 2 3 4 5

In-Order Traversal Example: printing 6 2 7 Current Node: 5 current not NULL recurse left print "5" recurse right (function ends) 1 5 3 4 Output: 1 2 3 4 5

In-Order Traversal Example: printing 6 2 7 Current Node: 2 current not NULL recurse left print "2" recurse right (function ends) 1 5 3 4 Output: 1 2 3 4 5

In-Order Traversal Example: printing 6 2 7 Current Node: 6 current not NULL recurse left print "6" recurse right 1 5 3 4 Output: 1 2 3 4 5 6

In-Order Traversal Example: printing 6 2 7 Current Node: 7 current not NULL recurse left 1 5 3 4 Output: 1 2 3 4 5 6

In-Order Traversal Example: printing 6 2 7 1 5 Current Node: NULL current NULL, return 3 4 Output: 1 2 3 4 5 6

In-Order Traversal Example: printing 6 2 7 Current Node: 7 current not NULL recurse left print "7" recurse right 1 5 3 4 Output: 1 2 3 4 5 6 7

In-Order Traversal Example: printing 6 2 7 1 5 Current Node: NULL current NULL, return 3 4 Output: 1 2 3 4 5 6

In-Order Traversal Example: printing 6 2 7 Current Node: 7 current not NULL recurse left print "7" recurse right (function ends) 1 5 3 4 Output: 1 2 3 4 5 6 7

In-Order Traversal Example: printing 6 2 7 Current Node: 6 current not NULL recurse left print "6" recurse right (function ends) 1 5 3 4 Output: 1 2 3 4 5 6 7