---
# System prepended metadata

title: 'CS2040 T04 Tutorial 5: Heaps and Priority Queues'

---

# CS2040 T04 Tutorial 5: Heaps and Priority Queues
> [name=jiachen]

## Recap

## Problem 1: True of False?

> For each of the following, determine if the statement is True or False, justifying your answer with appropriate explanation.

a. The smallest element in a min heap is always the root.

**TRUE**

b. The second largest element in a max heap with more than two elements (all elements are unique) is always one of the children of the root.

**TRUE**

c. When a heap is stored in an array, finding the parent of a node takes at least O(log n) time.

**FALSE**

d. Every node in the heap except the leaves has exactly 2 children

**FALSE**

e. We can obtain a sorted sequence of the heap elements in O(n) time.

**FALSE**

---

## Problem 2: Greater than x

Give an algorithm to find all vertices bigger than some value x in a max heap that runs in O(k) time where k is the number of vertices in the output.

#### Algorithm
```python=
def find_nodes_bigger(node, x):
    if node && node.key >= x:
        print(node.key)
        find_nodes_bigger(node.left, x)
        find_nodes_bigger(node.right, x)
        
# print out all nodes larger than in the tree
find_nodes_bigger(root, 10)
```

#### Analysis

**O(k + 2k)**, 
- k nodes that have keys greater than x are guaranteed to be visited. 
- For each of these k nodes there can be at most 2k additional calls to nodes with value smaller than x.

---

## Problem 3: Updating a heap
> Give an algorithm for the update(int old key, int new key) operation, which updates the value of old key in a binary heap (max or min) with new key in the binary heap in O(log n) time, which does not change the time complexity of the other operations.

> You are required to modify the other operations in the binary heap if needed, including any additional data structures used. 

> You may assume all values in the heap will be unique.

The problem: It takes O(n) to traverse the array to look for the key to replace!

Solution: Maintain an additional hashtable to lookup keys to index. We can build this hashtable when `heapify` is called in O(n) time. `swap` in `shiftup` and `shiftdown` will now have to update the hashtable.

- update* in O(log n)
    - lookup key index O(1)
    - update new key O(1)
    - call shift up O(log n)
    - call shift down O(log n)
- insert in O(log n) 
- extractMax in O(log n)
- heapify in O(n)
    - build hash table

---

## Problem 4: Sorted? Almost.

```
k = 1
array = [1, 3, 2, 4, 5, 7, 6]

k = 2
array = [1, 4, 3, 2, 6, 5, 7]
```

|true position - actual position| <= k


### a) Give an algorithm to sort a partially sorted array in O(n) time, where k = 1.

- one pass bubble sort


### b) Give an algorithm to sort a partially sorted array in O(n log k) time, where k can be any positive integer smaller than n.

- k pass bubble sort? O(nk)
- ignore everything focus on the first element
- what are the possible positions for the first elem?
- sliding heap window

```
k = 4
[|5, 2, 3, 4, 1|, 6, 7, 8, 9]
[|5, 2, 3, 4, 1,| 6, 7, 8, 9]
[1,  |5, 2, 3, 4, 6|, 7, 8, 9]
[1, 2,  |5, 3, 4, 6|, 7, 8, 9]

```

#### Algorithm
```python
def sort(arr, k):
    n = len(arr)
    
    # assume a new heap is provided
    h = heapify(arr[:k+1 # O(k)
    
    for i in range(n): # O(n)
        arr[i] = h.extractMin() # O(log k)
        
        if i + k + 1 < n:
            h.insert(arr[i + k + 1])# O(log k)
```

#### Analysis
O(k + n 2 log k)
= O(n log k) 

--- 

## Problem 5

### Algorithm

k = 2, score = 4
[2, -10, 2, -6, 5]

k = 5, score = 9
[-1, -1, -1, -1, -1, 10]


![](https://i.imgur.com/GZ0jvId.png)

### Analysis
Time: O(n log k)
Space: O(k)