IndexMinPQ
MinPQ: Min-Heap A complete binary tree Root has smaller value than both children No relation between left and right children
Min-Heap Insert / Remove: Swim and Sink Heap property must be maintained 5 14 23 32 41 87 90 50 64 53
Min-Heap example Representation 5 14 23 Array (index starting at 0) Parent is i Left: i * 2 Right: i * 2 + 1 32 41 87 90 50 64 53 1 2 3 4 5 6 7 8 9 10 5 14 23 32 41 87 90 50 64 53
Min-Heap example Insert (Swim) 5 14 23 Insert 43 32 41 87 90 50 64 53 private void swim(int k) { while (k > 1 && greater(k/2, k)) { exch(k, k/2); k = k/2; } 1 2 3 4 5 6 7 8 9 10 11 5 14 23 32 41 87 90 50 64 53 43
Min-Heap example Insert (Swim) 5 Insert 18 14 23 32 41 87 90 50 64 53 43 18 private void swim(int k) { while (k > 1 && greater(k/2, k)) { exch(k, k/2); k = k/2; } 1 2 3 4 5 6 7 8 9 10 11 12 5 14 23 32 41 87 90 50 64 53 43 18
Min-Heap example Insert (Swim) 5 Insert 18 14 23 32 41 18 90 50 64 53 43 87 private void swim(int k) { while (k > 1 && greater(k/2, k)) { exch(k, k/2); k = k/2; } 1 2 3 4 5 6 7 8 9 10 11 12 5 14 23 32 41 18 90 50 64 53 43 87
Min-Heap example Insert (Swim) 5 Insert 18 14 18 32 41 23 90 50 64 53 43 87 private void swim(int k) { while (k > 1 && greater(k/2, k)) { exch(k, k/2); k = k/2; } 1 2 3 4 5 6 7 8 9 10 11 12 5 14 18 32 41 23 90 50 64 53 43 87
Min-Heap example Remove (Sink) 5 14 18 32 41 23 90 50 64 53 43 87 1 2 Remove min Return `5` Swap 87 14 18 32 41 23 90 50 64 53 43 87 private void sink(int k) { while (2*k <= n) { int j = 2*k; if (j < n && greater(j, j+1)) j++; if (!greater(k, j)) break; exch(k, j); k = j; } 1 2 3 4 5 6 7 8 9 10 11 12 5 14 18 32 41 23 90 50 64 53 43 87
Min-Heap example Remove (Sink) 87 14 18 32 41 23 90 50 64 53 43 1 2 3 private void sink(int k) { while (2*k <= n) { int j = 2*k; if (j < n && greater(j, j+1)) j++; if (!greater(k, j)) break; exch(k, j); k = j; } 1 2 3 4 5 6 7 8 9 10 11 12 87 14 18 32 41 23 90 50 64 53 43 -1
Min-Heap example Remove (Sink) 14 87 18 32 41 23 90 50 64 53 43 1 2 3 private void sink(int k) { while (2*k <= n) { int j = 2*k; if (j < n && greater(j, j+1)) j++; if (!greater(k, j)) break; exch(k, j); k = j; } 1 2 3 4 5 6 7 8 9 10 11 12 14 87 18 32 41 23 90 50 64 53 43 -1
Min-Heap example Remove (Sink) 14 32 18 87 41 23 90 50 64 53 43 1 2 3 private void sink(int k) { while (2*k <= n) { int j = 2*k; if (j < n && greater(j, j+1)) j++; if (!greater(k, j)) break; exch(k, j); k = j; } 1 2 3 4 5 6 7 8 9 10 11 12 14 32 18 87 41 23 90 50 64 53 43 -1
Min-Heap example Remove (Sink) 14 32 18 50 41 23 90 87 64 53 43 1 2 3 private void sink(int k) { while (2*k <= n) { int j = 2*k; if (j < n && greater(j, j+1)) j++; if (!greater(k, j)) break; exch(k, j); k = j; } 1 2 3 4 5 6 7 8 9 10 11 12 14 32 18 50 41 23 90 87 64 53 43 -1
IndexMinPQ ChangeKey n = new CardPrice("NE", 333.0); 349 ChangeKey n = new CardPrice("NE", 333.0); a = new CardPrice("AMZN", 339.0); x = new CardPrice("NCIX", 338.0); b = new CardPrice("BB", 349.0); Update price for NE: 340.00 Update price for NCIX: 345.00 Update price for BB: 200.00 339 333 338
IndexMinPQ ChangeKey Find the index in the array Some operation 349 339 333 338
IndexMinPQ 349 ChangeKey If we know the entry, what operation should we process ? We changed the key, we need to maintain the heap property. 339 333 338 Update price for NCIX: 345.00
IndexMinPQ - ChangeKey public void changeKey(int i, Key key) { keys[i] = key; swim(qp[i]); sink(qp[i]); } We process both swim and sink since the entry may be arbitrary. 349 339 333 338 345 Update price for NCIX: 345.00
IndexMinPQ - ChangeKey public void changeKey(int i, Key key) { keys[i] = key; swim(qp[i]); sink(qp[i]); } We process both swim and sink since the entry may be arbitrary. 349 339 305 333 338 Update price for AMZN: 305.00
IndexMinPQ - ChangeKey changeKey(int i, Key key) Given the hash key `i`, change its associated sorting key to `key` E.g. Update price for AMZN: 305.00 Three mappings qp: hash key to index, e.g., qp[`NE`]=2 pq: index to hash key, e.g., pq[2]=`NE` keys: hash key to sorting key, e.g., keys[`NE`]=333
IndexMinPQ - ChangeKey 349 IndexMinPQ - ChangeKey 339 305 333 In the textbook example, hash key can only be integer, (`i` here) public void changeKey(int i, Key key) { keys[i] = key; swim(qp[i]); sink(qp[i]); } Hash key and sorting key Hash key: i (`NE`, `AMZN`, `NCIX`, `BB`) Sorting key: key (349, 305, 333, 338) `pq` and `qp` in the textbook example `qp`: a mapping from hash key to the index in the array `pq`: a mapping from index of the array to hash key `keys`: priority mapping Map hash keys to sorting keys 338 Update price for AMZN: 305.00 qp pq[0]=`BB` pq[1]=`AMZN` pq[2]=`NE` pq[3]=`NCIX` keys[`NE`]=333 keys[`AMZN`]=339 keys[`NCIX`]=338 keys[`BB`]=349 1 2 3 4 349 339 333 338
IndexMinPQ - ChangeKey private boolean greater(int i, int j) { return keys[pq[i]].compareTo(keys[pq[j]]) > 0; } private void swim(int k) { while (k > 1 && greater(k/2, k)) { exch(k, k/2); k = k/2; } private void sink(int k) { while (2*k <= n) { int j = 2*k; if (j < n && greater(j, j+1)) j++; if (!greater(k, j)) break; exch(k, j); k = j; private void exch(int i, int j) { int swap = pq[i]; pq[i] = pq[j]; pq[j] = swap; qp[pq[i]] = i; qp[pq[j]] = j; } public void changeKey(int i, Key key) { keys[i] = key; swim(qp[i]); sink(qp[i]); } Find what we are comparing Find what we are exchanging qp: hash key to index pq: index to hash key keys: hash key to sorting key
349 IndexMinPQ - delete 339 333 public void delete(int i) { int index = qp[i]; exch(index, n--); swim(index); sink(index); keys[i] = null; qp[i] = -1; } 338