Lecture 23: Priority Queues 10:00 AM, Mar 19, 2018

Similar documents
Lecture 23: Priority Queues, Part 2 10:00 AM, Mar 19, 2018

Lecture 24: Implementing Heaps 10:00 AM, Mar 21, 2018

Homework 6: Heaps Due: 5:00 PM, Apr 9, 2018

/633 Introduction to Algorithms Lecturer: Michael Dinitz Topic: Priority Queues / Heaps Date: 9/27/17

Lab 9: More Sorting Algorithms 12:00 PM, Mar 21, 2018

Lecture 21: The Many Hats of Scala: OOP 10:00 AM, Mar 14, 2018

Figure 1: A complete binary tree.

CMSC 341 Priority Queues & Heaps. Based on slides from previous iterations of this course

CMSC 341 Lecture 14: Priority Queues, Heaps

3. Priority Queues. ADT Stack : LIFO. ADT Queue : FIFO. ADT Priority Queue : pick the element with the lowest (or highest) priority.

Computational Optimization ISE 407. Lecture 16. Dr. Ted Ralphs

Treaps. 1 Binary Search Trees (BSTs) CSE341T/CSE549T 11/05/2014. Lecture 19

Recall: Properties of B-Trees

CSE 2123: Collections: Priority Queues. Jeremy Morris

CSE 332: Data Structures & Parallelism Lecture 3: Priority Queues. Ruth Anderson Winter 2019

- Alan Perlis. Topic 24 Heaps

BINARY HEAP cs2420 Introduction to Algorithms and Data Structures Spring 2015

Lecture 22: Garbage Collection 10:00 AM, Mar 16, 2018

Computer Science 210 Data Structures Siena College Fall Topic Notes: Priority Queues and Heaps

9. Heap : Priority Queue

Binary Heaps. CSE 373 Data Structures Lecture 11

Lecture 11: In-Place Sorting and Loop Invariants 10:00 AM, Feb 16, 2018

Binary heaps (chapters ) Leftist heaps

Priority Queues Heaps Heapsort

(Provisional) Lecture 32: Estimated Value, Minimax, Functional Data 10:00 AM, Nov 20, 2017

Lecture 5. Treaps Find, insert, delete, split, and join in treaps Randomized search trees Randomized search tree time costs

Data structures. Priority queues, binary heaps. Dr. Alex Gerdes DIT961 - VT 2018

PRIORITY QUEUES AND HEAPS

Priority Queues. 1 Introduction. 2 Naïve Implementations. CSci 335 Software Design and Analysis III Chapter 6 Priority Queues. Prof.

Priority Queues and Heaps

So on the survey, someone mentioned they wanted to work on heaps, and someone else mentioned they wanted to work on balanced binary search trees.

Exam Data structures DIT960/DAT036

Binary Trees

Trees 2: Linked Representation, Tree Traversal, and Binary Search Trees

Lecture Notes on Priority Queues

Homework 4: Hash Tables Due: 5:00 PM, Mar 9, 2018

Programming II (CS300)

Data Structures Lesson 9

Lecture 13: AVL Trees and Binary Heaps

Lecture 23: Priority Queues, Part 2 10:00 AM, Mar 19, 2018

Priority Queues, Binary Heaps, and Heapsort

CS558 Programming Languages

CS 270 Algorithms. Oliver Kullmann. Binary search. Lists. Background: Pointers. Trees. Implementing rooted trees. Tutorial

PRIORITY QUEUES AND HEAPS

(Provisional) Lecture 22: Rackette Overview, Binary Tree Analysis 10:00 AM, Oct 27, 2017

Binary Search Trees Treesort

Algorithms and Data Structures

CSCI 136 Data Structures & Advanced Programming. Lecture 22 Fall 2018 Instructor: Bills

CSCI-1200 Data Structures Fall 2018 Lecture 22 Hash Tables, part 2 & Priority Queues, part 1

CSE100. Advanced Data Structures. Lecture 12. (Based on Paul Kube course materials)

Priority Queues. Binary Heaps

CSE100. Advanced Data Structures. Lecture 8. (Based on Paul Kube course materials)

CS558 Programming Languages

COMP 250 Fall priority queues, heaps 1 Nov. 9, 2018

Section 4 SOLUTION: AVL Trees & B-Trees

Binary Heaps. COL 106 Shweta Agrawal and Amit Kumar

Algorithms in Systems Engineering ISE 172. Lecture 16. Dr. Ted Ralphs

Priority Queues Heaps Heapsort

Programming II (CS300)

CSE 214 Computer Science II Heaps and Priority Queues

PRIORITY QUEUES AND HEAPS

INF2220: algorithms and data structures Series 4

CS2 Algorithms and Data Structures Note 6

COS 226 Midterm Exam, Spring 2009

CS24 Week 8 Lecture 1

Thus, it is reasonable to compare binary search trees and binary heaps as is shown in Table 1.

The fringe of a binary tree are the values in left-to-right order. For example, the fringe of the following tree:

Readings. Priority Queue ADT. FindMin Problem. Priority Queues & Binary Heaps. List implementation of a Priority Queue

COMP 103 RECAP-TODAY. Priority Queues and Heaps. Queues and Priority Queues 3 Queues: Oldest out first

CS 241 Analysis of Algorithms

CS 234. Module 8. November 15, CS 234 Module 8 ADT Priority Queue 1 / 22

Lecture 17 Priority Queues

CSE 373 OCTOBER 11 TH TRAVERSALS AND AVL

Lecture 7: Implementing Lists, Version 2

Lecture 26: Graphs: Traversal (Part 1)

CS350: Data Structures Heaps and Priority Queues

Data Structures and Algorithms Dr. Naveen Garg Department of Computer Science and Engineering Indian Institute of Technology, Delhi

Summer Final Exam Review Session August 5, 2009

CMSC 341 Leftist Heaps

Subject : Computer Science. Paper: Data Structures. Module: Priority Queue and Applications. Module No: CS/DS/14

Lecture 8: Iterators and More Mutation

CSE100. Advanced Data Structures. Lecture 13. (Based on Paul Kube course materials)

CSE373: Data Structures & Algorithms Lecture 9: Priority Queues and Binary Heaps. Linda Shapiro Spring 2016

Priority Queues. 04/10/03 Lecture 22 1

CS61B Fall 2014 Guerrilla Section 2 This worksheet is quite long. Longer than we ll cover in guerrilla section.

Chapter 6 Heaps. Introduction. Heap Model. Heap Implementation

Binary Search Trees. Carlos Moreno uwaterloo.ca EIT

Trees 2: Linked Representation, Tree Traversal, and Binary Search Trees

CS2 Algorithms and Data Structures Note 6

COMP : Trees. COMP20012 Trees 219

Sorting and Searching

Total Score /1 /20 /41 /15 /23 Grader

TREES Lecture 12 CS2110 Fall 2016

Recitation 9. Prelim Review

CS302 Data Structures using C++

Total Score /15 /20 /30 /10 /5 /20 Grader

CMSC 341 Lecture 15 Leftist Heaps

Data Structures and Algorithms

MID TERM MEGA FILE SOLVED BY VU HELPER Which one of the following statement is NOT correct.

CSCI-1200 Data Structures Spring 2016 Lecture 22 Priority Queues, part II (& Functors)

Transcription:

CS18 Integrated Introduction to Computer Science Fisler, Nelson Lecture 23: Priority Queues 10:00 AM, Mar 19, 2018 Contents 1 Priority Queues 1 2 Binary Heaps 2 3 Heaps 4 4 Aside: The Ordered Trait 5 5 Another Digression: Trees as Arrays 7 Objectives By the end of these notes, you will know: ˆ what a heap is ˆ what a priority queue is By the end of these notes, you will be able to: ˆ implement a mutable tree using an array 1 Priority Queues By now you are familiar with a number of abstract data types, including lists, stacks, queues, maps (i.e., dictionaries), and sets. The next abstract data type you will learn about is the priority queue. A priority queue is useful for storing a collection of data whenever each datum is accompanied by a value, its so-called priority. These priorities are used to you guessed it prioritize elements of the collection. Together they determine an order in which the elements of the collection are visited. Priority queues generalize both stacks and queues. A stack is a priority queue in which the last element inserted has highest priority (i.e., it is visited first). A queue is a priority queue in which the first element inserted has highest priority (i.e., it is visited first). The operations required by a typical priority queue interface, in which lower 1 priority elements of the collection are visited first, are: 1 We could just as well implement a priority queue in which elements with higher priorities are visited first.

// T is the type of an item; S is the type of its priority trait IPriorityQueue[T, S] { * @return optionally, the item in the heap of lowest priority def getminitem: Option[T] * @return optionally, the priority of the item in the heap of lowest priority def getminpriority: Option[S] * Deletes the lowest - valued item from the priority queue * * @return optionally, the lowest - valued item in the priority queue def deletemin: Option[T] * Inserts an item into the priority queue * * @param item - an item to insert into the priority queue * def insert(item: T, priority: S) When are priority queues useful? Anywhere that your program may be adding values with arbitrary priority to the queue. Consider a hospital emergency room: patients are constantly arriving, some with more serious injuries than many who have already been waiting. Those new arrivals should be seen sooner because their needs are more dire. If we just used an ordinary queue, patients would be seen in arrival order! The main topic of these notes is heaps, a data structure for implementing priority queues. But before we discuss heaps, let s think about why the data structures you ve already learned about are not suitable for this task. Take linked lists, for example. We can insert new elements into a linked list in constant time. But, if we were to do so, then we could not find an element of minimal priority in constant time; we would have to search through the entire list to find one. On the other hand, if we were to maintain a sorted linked list, then we could find an element of minimal priority in constant time. But then, the insert operation would take linear time, because we would have to search for the appropriate location at which to insert the elements. So linked lists won t do. What about a hash table? Unfortunately, they suffer from many of the same issues: we can t hash priorities, because that would obliterate the ordering, and so we d have to fully traverse all buckets. What about trees? Well, a heap is actually a kind of a tree, just like a binary search tree is a kind of a tree. So, yes, trees are the answer. 2

2 Binary Heaps Recall from CS 17 the definition of binary search trees. A binary search tree is a binary tree in which the following left and right invariants hold: ˆ Every value in a node s left subtree must be less than its value; and ˆ Every value in a node s right subtree must be greater than its value. Here s an example of a binary search tree (shamelessly stolen from the CS 17 notes): 5 3 7 1 4 6 11 A binary heap is like a binary search tree in that it is a binary tree for which a certain invariant holds. More specifically, there are two kinds of heaps, and for each kind, there is an invariant: ˆ min-heap: Every node s value is less than or equal to its children s values. ˆ max-heap: Every node s value is greater than or equal to its children s values. The tree below is an example of a min-heap, because 1, the root node, is the smallest value in the tree; 3 is the smallest value in the subtree for which it is the root node; and 4 is the smallest value in the subtree for which it is the root node. (We will swap between min- and max-heaps as needed, the important piece of information is that more important entries are always higher in the tree.) 1 3 4 6 5 7 11 Here are the same values again depicted in a max-heap: 3

11 5 7 4 3 1 6 And another: 11 7 6 4 3 1 5 At this point, it s reasonable to ask whether balance matters. Recall that, for binary search trees, an unbalanced tree could result in linear-time operations far worse than the logarithmic time provided by balanced trees. It turns out that the same issues arise with heaps. For instance, this heap is not balanced even though it technically satisfies the max-heap condition: 11 5 4 We ll see why balanced heaps are easier to work with in the next lecture. For now, just keep in mind that balance is a separate property; i.e., not implied by the min-heap or max-heap properties. Finally, note that the nodes in BSTs and heaps can store objects of any type, including pairs. So just as BSTs are often used to implement dictionaries (i.e., sets of key-value pairs), heaps are often used to implement priority queues (i.e., sequences of items sorted by their priorities). 3 Heaps Just like we built hash tables atop arrays, we will build the priority queue interface via a still more abstract interface, which we call IHeap. This interface is nearly identical to that of priority queues, only it is parameterized by a single type, rather than two (and, consequently, it has only a single getmin method). 4

trait IHeap[T] { * @return optionally, the lowest - valued item in the heap def getmin: Option[T] * Deletes the lowest - valued item from the heap * * @return optionally, the lowest - valued item in the heap def deletemin: Option[T] * Inserts item into the heap * * @param item - an item to insert into the heap * def insert(item: T) Given this interface for heaps, our strategy for implementing priority queues will be as follows: 1. We will create a class Heap[T] that implements IHeap[T]. 2. We will implement IPriorityQueue[T, S] with a heap that stores item-prioritypairs. That is, the T that parameterizes Heap will not be the same T as the item-type in IPriorityQueue. 4 Aside: The Ordered Trait Before we can implement heaps, we need to say a few words about ordering. Being able to compare priorities essential to a heap s operation. Priorities need not always be a single number. For instance, back in our hospital emergency-room example, the policy might be to see patients in worse condition first, but if two patients have the same condition, they should be seen in order of their arrival. Here, a priority is actually a pair: one number for arrival time, and one number for how urgent their case is. Let s say that we want to take our standard binary-search implementation and generalize it so that it can search an array of type T, rather than an array of any specific type, such as Int. But T cannot really be just any old type. On the contrary, T must implement Ordered[T], an interface that ensures that T is totally ordered, so that either a < b, a > b, or a == b, for all elements a and b of T. Scala s Ordered trait extends Java s Comparable interface. Both have an abstract method compare, which must be defined by all classes that implement this trait/interface. Here is the signature for compare (using Scala syntax): abstract def compare(that: T): Int 5

Based on its signature, we can infer that the compare method returns the result of comparing object this with argument that, with this result encoded as an Int. The convention that governs Scala s compare method 2 is: return x, where ˆ x < 0 if this < that ˆ x = 0 if this equals that ˆ x > 0 if this > that Because T is totally ordered, exactly one of these cases must hold. Given a concrete definition of compare, Scala infers the definitions of related operators. In particular, the Ordered trait defines <, >, <=, and >= as follows: trait Ordered[T] { def <(that: T): Boolean = (this compare that) < 0 def >(that: T): Boolean = (this compare that) > 0 def <=(that: T): Boolean = (this compare that) <= 0 def >=(that: T): Boolean = (this compare that) >= 0 For example, since String implements Ordered[String], we can write predicates like "cs16"< " cs18". You don t need to write these yourself; just define the compare function for your class, and you ll be able to use <, etc. for free. The syntax for declaring a class that is necessarily Ordered is as follows: class MyClass[T <: Ordered[T]]. This is Scala s analog of the Java syntax class MyClass<T extends Comparable <T>>. In the interest of efficiency, some basic Scala classes, like Int and Double (i.e., the analog of Java s primitive types), do not implement the Ordered trait. Consequently, the following class, which is parameterized by an ordered type T, cannot be instantiated using Int: scala> class MyClass[T <: Ordered[T]] defined class MyClass scala> val broken = new MyClass[Int]() <console>:9: error: type arguments [Int] do not conform to class MyClass's type par val broken = new MyClass[Int]() There are two ways to fix this problem. The first is to use RichInt, which does implement Ordered. But that is somewhat inconvenient and unnatural. Instead, we will just tell the Scala compiler to perform implicit conversion when necessary. To do this, we subtly change the way we declare that T extends Ordered[T]. Instead of using <:, we will use <%. This will tell Scala to implicitly convert where appropriate. Thus, the type signature of binary search will change from something like: 2 and Java s, and most other mainstream programming languages 6

def binarysearch(myarray: Array[Int], key: Int): Option[Int] = {... to: def binarysearch[t <% Ordered[T]](myArray: Array[T], key: T): Option[T] = {... The remarkable thing is that our final implementation requires no changes to the binary search methods themselves! 5 Another Digression: Trees as Arrays One straightforward way to implement (mutable) trees is as a generalization of linked lists. But trees need not be implemented using a linked data structure. Instead, they can be implemented using arrays. Take, for example, the following binary tree: 1 3 4 6 5 7 11 Suppose we label the vertices with numbers assigned in breadth-first order. That is, starting with 0, we label the nodes in order from depth 0 to depth n, and at each level from left to right. Here s the corresponding numbering: 0 1 2 3 4 5 6 Given this assignment, we can now store our tree in an array. If we call this array tree, then tree[0] = 1, tree[1] = 3, tree[2] = 4, tree[3] = 6, and so on. What can we say about the indices at which a node s left and right children, and its parent, are stored? Here s a table that should give us some clues: 7

Datum Index Left Right Parent 1 0 1 2 3 1 3 4 0 4 2 5 6 0 6 3 1 5 4 1 7 5 2 11 6 2 The node stored at index 0 (i.e., the root) has no parent. Similarly, the nodes stored at indices 3 through 6 (i.e., the leaves) have no children. Otherwise, we can derive the following formulas for computing the indices of the left and right children, respectively, of the node stored at index i: the left child s index is 2i + 1, and the right child s index is 2i + 2. Furthermore, the parent s index is (i 1)/2. 3 Please let us know if you find any mistakes, inconsistencies, or confusing language in this or any other CS18 document by filling out the anonymous feedback form: http://cs.brown.edu/ courses/cs018/feedback. 3 The parents index can also be expressed as i/2 1. 8