Illustrates the use of the PriorityQueue constructor and methods
What is the worst-case time complexity of these methods?
Creating and using a MaxHeap
# create a PriorityQueue instance where the# key is the opposite of the input value of xmaxheap = PriorityQueue(key =lambda x: -x)# does not specify a priority for a valuen =10for i inrange(n): maxheap.insert(i)# displays the values in decreasing orderprint([maxheap.removemin() for _ inrange(n)])
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Creates a PriorityQueue to store values in decreasing order
Conveniently coalesces the key and the value into a single key
Note that the removemin function was not changed in any way!
Performing a HeapSort
def heapsort(L): H = PriorityQueue(L) L[:] = [item for item in H]L = [3, 2, 4, 1, 6, 5]print("Before heapsort:", L)heapsort(L)print("After heapsort: ", L)
Before heapsort: [3, 2, 4, 1, 6, 5]
After heapsort: [1, 2, 3, 4, 5, 6]
Uses the _heapify method to create a PriorityQueue in \(O(n)\)
Iteration over each item in list comprehension costs \(O(\log n)\)
This means that the heapsort function has a time complexity of \(O(n \log
n)\). Is this better, worse, or the same as mergesort?
Define a Job class with name, priority, and duration
Create three Job instances with different priorities and durations
Running Jobs with a PriorityQueue
# run all of the jobs in order of prioritywhilenotlen(job_queue) ==0: next_job = job_queue.removemin()print(f"Running {next_job}")for i inrange(next_job.duration):print(f"{next_job.name} is running...")print(f"{next_job.name} has finished running.")
Running Job: Medium-running job 2, Priority: 1, Duration: 2
Medium-running job 2 is running...
Medium-running job 2 is running...
Medium-running job 2 has finished running.
Running Job: Short-running job 3, Priority: 2, Duration: 1
Short-running job 3 is running...
Short-running job 3 has finished running.
Running Job: Long-running job 1, Priority: 3, Duration: 5
Long-running job 1 is running...
Long-running job 1 is running...
Long-running job 1 is running...
Long-running job 1 is running...
Long-running job 1 is running...
Long-running job 1 has finished running.
Comparing PriorityQueue structures
UnsortedListPQ
Uses an unsorted list to store entries
Fast: insert method is \(O(1)\)
Slow: findmin and removemin methods are \(O(n)\)
SortedListPQ
Uses a sorted list to store entries
Slow: insert method is \(O(n \times log_2n)\)
Fast: findmin and removemin methods are \(O(1)\)
HeapPQ and PriorityQueue
Performance analysis:
Uses a binary heap to store entries
Fast: insert, findmin, and removemin are \(O(\log_2 n)\)
Trade-offs: no more constant-time complexity methods!
Functionality review:
PriorityQueue extends HeapPQ and adds more methods
PriorityQueue offers random access to remove any item
PriorityQueue supports iteration to remove all items