1 CSCI 104 Priority Queues / Heaps Mark Redekopp David Kempe Sandra Batista
2 PRIORITY QUEUES
3 Traditional Queue • Traditional Queues (push_back) – Accesses/orders items based on POSITION 47 (front/back) (pop_front) – Did not care about item's VALUE 15 33 62 81 • Priority Queue – Orders items based on VALUE • Either minimum or maximum Traditional Queue – Items arrive in some arbitrary order – When removing an item, we always want the (push) 47 minimum or maximum depending on the implementation (pop) 15 33 62 81 • Heaps that always yield the min value are called min-heaps • Heaps that always yield the max value are called max-heaps Priority Queue – Leads to a "sorted" list – Examples: • Think hospital ER, air-traffic control, etc.
4 Priority Queue class Patient { • What member functions does a Priority Queue have? public: bool operator<(...); – push(item) – Add an item to the appropriate location of the }; PQ – top() – Return the min./max. value (push) P6 – (top) pop() - Remove the front (min. or max) item from the PQ – (pop) size() - Number of items in the PQ P2 P3 P4 P5 – empty() - Check if the PQ is empty P1 – [Optional]: changePriority(item, new_priority) • Useful in many algorithms (especially graph and search Priority Queue algorithms) (Priority based on intrinsic property of the data) • Priority can be based on… – Intrinsic data-type being stored (i.e. operator<() (push) 47, of type T) (top) P6 – Separate parameter from data type, T, and (pop) 12, 17, 31, 39, passed in which allows the same object to have P1 P2 P3 P5 P1 different priorities based on the programmer's desire (i.e. same object can be assigned different Priority Queue priorities) (Priority based on separate priority parameter)
5 Priority Queue Efficiency • If implemented as a sorted array list – Insert() = ___________ – Top() = ___________ – Pop() = ____________ • If implemented as an unsorted array list – Insert() = ___________ – Top() = ___________ – Pop() = ____________
6 Priority Queue Efficiency • If implemented as a sorted array list – [Use back of array as location of top element] – Insert() = O(n) – Top() = O(1) – Pop() = O(1) • If implemented as an unsorted array list – Insert() = O(1) – Top() = O(n) – Pop() = O(n)
7 HEAPS
8 Heap Data Structure • Provides an efficient implementation for a priority queue • Can think of heap as a complete binary tree that maintains the heap property : – Heap Property : Every parent is less-than (if min-heap) or greater-than (if max-heap) both children, but no ordering property between children • Minimum/Maximum value is always the top element 7 18 9 Always a complete tree 19 35 14 10 28 39 36 43 16 25 Min-Heap
9 Heap Operations • Push: Add a new item to the heap and modify heap as template <typename T> necessary class MinHeap { public: • Pop: Remove min/max item MinHeap(int init_capacity); ~MinHeap() and modify heap as void push(const T& item); T& top(); necessary void pop(); int size() const; • Top: Returns min/max bool empty() const; private: • Since heaps are complete // Helper function void heapify(int idx); binary trees we can use an vector<T> items_; // or array array/vector as the } container
10 Array/Vector Storage for Heap • Recall: A complete binary tree (i.e. only the lowest-level contains empty locations and items added left to right) can be modeled as an array (let’s say it starts at index 1) where: – Parent(i) = i/2 – Left_child(p) = 2*p – Right_child(p) = 2*p + 1 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 7 em 7 18 9 19 35 14 10 28 39 36 43 16 17 2 3 18 9 4 5 6 7 19 35 14 10 Parent(5) = 5/2 = 2 Left(5) = 2*5 = 10 11 12 9 10 13 14 8 Right(5) = 2*5+1 = 11 28 39 36 43 16 17
11 Array/Vector Storage for Heap • We can also use 0-based indexing – Parent(i) = ______ – Left_child(p) = ______ – Right_child(p) = ______ 0 0 1 2 3 4 5 6 7 8 9 10 11 12 7 7 18 9 19 35 14 10 28 39 36 43 16 17 1 2 18 9 3 4 5 6 19 35 14 10 9 10 11 8 12 7 28 39 36 43 16 17
12 Push Heap / TrickleUp • Add item to first free location at void MinHeap<T>::push(const T& item) { items_.push_back(item); bottom of tree trickleUp(items_.size()-1); } • Recursively promote it up while void MinHeap<T>::trickleUp(int loc) it is less than its parent { // could be implemented recursively – Remember valid heap all parents int parent = _________; while(parent ______ && < children…so we need to promote items_[loc] ___ items_[parent] ) { swap(items_[parent], items_[loc]); it up until that property is satisfied loc = ___________; parent = ________; Solutions at the } end of these slides } 1 Push_Heap(8) 7 7 2 3 18 9 18 8 4 5 6 7 19 35 14 10 19 35 14 9 9 10 11 12 13 14 8 28 39 36 43 16 25 8 8 28 39 36 43 16 25 10
13 top() T const & MinHeap<T>::top() { • top() simply needs if( empty() ) throw(std::out_of_range()); return items_[1]; to return first item } Top() returns 7 1 7 2 3 18 9 4 5 6 7 19 35 14 10 9 10 11 12 13 8 28 39 36 43 16 25
14 Pop Heap / Heapify (TrickleDown) void MinHeap<T>::pop() { items_[1] = items_.back(); items_.pop_back() • Pop utilizes the "heapify" heapify(1); // a.k.a. trickleDown() } algorith (a.k.a. trickleDown) void MinHeap<T>::heapify(int idx) • Takes last (greatest) node { if(idx == leaf node) return; puts it in the top location int smallerChild = 2*idx; // start w/ left if(right child exists) { and then recursively swaps int rChild = smallerChild+1; if(items_[rChild] < items_[smallerChild]) it for the smallest child until smallerChild = rChild; } } it is in its right place if(items_[idx] > items_[smallerChild]){ swap(items_[idx], items_[smallerChild]); heapify(smallerChild); Original } } 1 1 7 7 25 9 9 3 3 2 2 18 9 18 9 18 10 4 5 6 4 5 6 7 7 19 35 14 10 19 35 14 10 19 35 14 25 11 12 11 12 9 10 13 9 10 8 8 28 39 36 43 16 25 28 39 28 39 36 43 16 36 43 16
15 Practice Push(11) Push(23) 1 1 7 7 2 3 2 3 18 9 18 21 4 5 6 4 5 6 7 7 19 35 14 10 19 35 26 24 9 10 11 12 9 10 13 8 28 39 36 28 39 36 43 29 50 Pop() Pop() 1 1 7 4 2 3 2 3 18 21 17 8 4 5 6 7 4 5 6 7 19 35 26 24 19 35 26 24 11 12 9 10 13 8 9 10 28 39 36 43 29 50 28 39 36
16 Building a heap out of an array HEAPSORT
17 Using a Heap to Sort • If we could make a valid heap out of an arbitrary array , could we use that heap to sort our data? • Sure, just call top() and pop() n times to get data in sorted order • How long would that take? – n calls to: top()= Θ (1) and pop()= Θ (log n) 0 1 2 3 4 5 6 7 8 – Thus total time = Θ (n * log n) em 7 9 14 10 35 28 18 19 • But how long does it take to convert the array Array Converted to Valid Heap 1 to a valid heap? 7 0 1 2 3 4 5 6 7 8 2 3 9 14 em 28 9 18 10 35 14 7 19 Arbitrary Array 4 5 6 7 1 10 35 28 18 28 2 3 9 18 8 Valid Heap 19 4 5 6 7 10 35 14 7 0 1 2 3 4 5 6 7 8 em 7 9 10 14 18 19 28 35 8 19 Complete Tree View of Array after top/popping the heap n times Arbitrary Array
18 make_heap(): Converting An Unordered Array to a Heap • We can convert an unordered array to a heap 0 1 2 3 4 5 6 7 8 – std::make_heap() does this em 28 9 7 10 35 18 14 19 Array not fulfilling heap property – Let's see how… (issue is 28 at index 1) • Basic operation: Given two heaps we 28 can try to make one heap by unifying 2 3 them with some new, arbitrary value 9 7 but it likely won't be a heap 4 5 6 7 10 35 18 14 • How can we make a heap from this non-heap 8 19 • Heapify!! (we did this in pop() ) A Valid Heap A Valid Heap Tree View of Array
19 Converting An Array to a Heap 0 1 2 3 4 5 6 7 8 • To convert an array to a heap we can em 28 9 18 10 35 14 7 19 use the idea of first making heaps of Original Array both sub-trees and then combining 1 the sub-trees (a.k.a. semi heaps) into 28 one unified heap by calling heapify() 2 3 9 18 on their parent() 4 5 6 7 10 35 14 7 • First consider all leaf nodes, are they 8 19 valid heaps if you think of them as the Tree View of Array root of a tree? – Yes!! • So just start at the first non-leaf
20 Converting An Array to a Heap 1 28 • First consider all leaf nodes, are they 2 3 9 18 valid heaps if you think of them as the root of a tree? 4 5 6 7 10 35 14 7 – Yes!! 8 • So just start at the first non-leaf 19 – Heapify(Loc. 4) Leafs are valid heaps by definition heapify(4) heapify(3) heapify(2) heapify(1) Swap 28 <-> 7 Already in the Swap 18 & 7 Already a heap Swap 28 <-> 14 right order 2 1 9 28 4 3 4 3 18 7 10 10 4 2 3 9 7 10 35 8 8 6 7 6 7 8 4 5 6 19 7 19 14 7 14 18 19 10 35 14 18 8 19
Recommend
More recommend