COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

20
COMP 103 Priority Queues, Partially Ordered Trees and Heaps

Transcript of COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

Page 1: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

CO

MP 1

03

Priority Queues,Partially Ordered Trees

and Heaps

Page 2: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

2

RECAP-TODAYRECAP

Clever stuff with linked structures linked list idea nice way to implement a Stack, or a

Queue Then we saw trees, and then Binary Search Trees

(BST) adding, and finding (significance of balance) removing is “interesting” BST idea nice way to implement a Set, Bag, or Map in-order traversals TreeSort

TODAY: Priority queue (PQ) – variation on queue – “best”

first partially ordered tree (POT) nice way to

implement PQ oh and we’ll also get another fast sorting

algorithm! Reading: Chapter 17 (section 17.4 - 17.5)

Page 3: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

3

Queues and priority queues Queues: First in, first out ⇒ Oldest out first

Priority Queues: Highest priority (“best”) out first

Emergency room, 111 calls, job scheduling in factory, etc... Operating system process scheduling Graph/network algorithms: route planning, find

shortest/cheapest path AI search algorithms

Bob Jack Jim Ian

Bob Jack Jim Ian143 2 Sometimes

low number means high priority!

Page 4: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

4

Implementing Priority Queues Unsorted list (array or linked list):

Fast to enqueue (“offer”): O(1) Slow to dequeue (“poll”): O(n)

have to search for highest priority item.

Sorted list (array or linked list): Fast to dequeue (“poll”): O(1) Slow to enqueue (“offer”): O(n)

have to search for insertion point (and move items up).

Array of “Buckets” of queues for each priority: Fast to enqueue and dequeue: O(1) Requires a small finite number of priorities. Best choice when applicable.

1

2

3

4

5

6

7

8

9

10

Page 5: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

5

Implementing Priority Queues: preview...

So, what to do when we have unlimited priorities?

Binary Search Tree: Keeps items in order, and allows easy insertion Fast to enqueue: O(log n) [if balanced] Fast to dequeue: O(log n) [if balanced] How?

But, hard to keep balanced

Partially Ordered Tree: Fast to enqueue (“offer”): O(log n) Fast to dequeue (“poll”): O(log n) Keeps itself balanced! Fast to construct from unordered list!

Page 6: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

6

Partially Ordered Trees

Binary Search Tree: Binary tree All left subtree < parent,

All right subtree ≥ parent.

Partially Ordered Tree

• Binary tree• Children ≤ parent,• Order of children not important

Cat19

Eel26

Gnu13

Fox3

Dog14

Bee35

Hen23

Ant9

Bee35

Eel26

Cat19

Dog14

Fox3

Ant9

Hen23

Gnu13

Jay1

Jay1

Keep largest (or smallest) element at the root.

Page 7: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

7

Partially Ordered Tree: add Easier to add and remove because the order is not

complete.

Add: insert at bottom rightmost “push up” to correct position.

(swapping)

Bee35

Eel26

Cat19

Dog14

Fox3

Ant9

Hen23

Gnu13

Jay1

Kea24

Page 8: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

8

Partially Ordered Tree: remove Easier to add and remove because the order is not

complete.

Add: insert at bottom rightmost “push up” to correct position.

Remove: “pull up” largest child

and recurse. But: makes tree unbalanced!

Bee35

Eel26

Kea24

Dog14

Cat19

Ant9

Hen23

Gnu13

Jay1

Fox3

Page 9: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

9

Partially Ordered Tree: remove I Easier to add and remove because the order is not

complete.

Add: insert at bottom rightmost “push up” to correct position.

Remove: “pull up” largest child of root

and recurse on that subtree. But: makes tree unbalanced!

Alternative: replace root by bottom rightmost node “push down” to correct position (swapping) keeps tree balanced – and complete!

Bee35

Eel26

Kea24

Dog14

Cat19

Ant9

Hen25

Gnu13

Jay1

Fox3

Page 10: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

10

Partially Ordered Tree: remove II Easier to add and remove because the order is not

complete.

Add: insert at bottom right “push up” to correct position.

Remove: “pull up” largest child

and recurse. But: makes tree unbalanced!

Alternative: replace root by bottom rightmost node “push down” to correct position keeps tree balanced – and complete!

Eel26

Hen23

Kea24

Dog14

Cat19

Ant9

Fox3

Gnu13

Jay1

Page 11: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

11

Partially Ordered Tree Add: insert at bottom rightmost,

swap with parent, … Remove: replace root with bottom rightmost,

swap with largest child, …

But: How do you find the bottom right? Once you have found it, how do

you find its parent to push it up?

We need a tree where you can quickly get to: the bottom right node, children from parent, parent from children.

Bee35

Eel26

Cat19

Dog14

Fox3

Ant9

Hen23

Gnu13

Jay1

Kea24

Page 12: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

12

Heap: A complete, partially ordered, binary tree

complete = every level full, except bottom, where nodes are to the left

Implemented in an array using breadth-first order

Bee35

Eel26

Kea19

Dog14

Fox7

Ant9

Hen23

Gnu13

Jay1

Cat4

Bee35

Eel26

Kea19

Dog14

Fox7

Ant9

Hen23

Gnu13

Jay1

Cat4

0 1 3 7 8 942 65

Page 13: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

13

Heap We can compute the index of parent and children of

a node: the children of node i are at (2i+1) and (2i+2)

the parent of node i is at (i-1)/2

Bottom right node is last element used.

There are no gaps!

Bee35

Eel26

Kea19

Dog14

Fox7

Ant9

Hen23

Gnu13

Jay1

Cat4

0 1 3 7 8 942 65

Bee35

Eel26

Kea19

Dog14

Fox7

Ant9

Hen23

Gnu13

Jay1

Cat4

Page 14: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

14

Heap: add

Insert at bottom of tree and push up: Put new item at end: 10

Compare with parent: (10-1)/2 = 4 ⇒ Fox/7 If larger than parent, swap

Compare with parent: (4-1)/2 = 1 ⇒ Kea/19 If larger than parent, swap

Compare with parent: (1-1)/2 = 0 ⇒ Bee/35

Bee35

Eel26

Kea19

Dog14

Fox7

Ant9

Hen23

Gnu13

Jay1

Cat4

0 1 3 7 8 942 65 10 11 12

10

Pig21

11

Page 15: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

15

Heap: remove

Remove item at 0: Move last item to 0 Find largest child 20+1 = 1, 20+2 = 2

If smaller than largest child, swap

Find largest child 22+1 = 5, 22+2 = 6 If smaller than largest child, swap

Find largest child 25+1 = 11 : No such child

Bee35

Eel26

Pig21

Dog14

Kea19

Ant9

Hen23

Gnu13

Jay1

Cat4

0 1 3 7 8 942 65 10 11 12

10

Fox7

11

Page 16: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

16

HeapQueuepublic class HeapQueue <E> extends AbstractQueue <E> {

private List<E> data =  new ArrayList<E>();private Comparator<E> comp;   

public HeapQueue (Comparator <E> c) {comp = c;

}

public boolean isEmpty() {return data.isEmpty();

}

public int size () {return data.size();

}

public E peek () {if (isEmpty())     return null;else    return data.get(0);

}

Use ArrayList, not array, so it handles resizing.

Comparator must be designed so that it

compares the priority values (not the items)

Note to whoever teaches this next:

I think it’d be better to present this in terms of ordinary array notation, because it’s easier to see what it’s doing, and leave it to them as an exercise to reimplement it using ArrayList once they understand it.

I think the coding used for pushup and pushdown (ie writing things like data.set(child, data.set(parent, data.get(child)));) is revolting and should not be inflicted up poor struggling first year students! I’ve changed it to use a method which at least makes the intention clear.

Also, this code doesn’t distinguish between the values in the priority queue and their priorities. It can be made to work IF the comparator you use can extract a priority from an object, but if that is what is intended, it needs to be explained.

I worked all this out too late to fix it this time round, so and adding this note to help whoever does it next time.

Lindsay

Page 17: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

17

HeapQueue: offer and pollpublic boolean offer(E value) {

if (value == null) return false;else {

data.add(value);pushup(data.size()-1);return true;

}}

public E poll() {if (isEmpty()) return null;if (data.size() == 1) return data.remove(0);else {

E ans = data.get(0);data.set(0, data.remove(data.size()-1));pushdown(0);return ans;

}}

add at the end of the array

move last element into root

Page 18: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

18

HeapQueue: pushupprivate void pushup(int child) {

if (child == 0) return;int parent = (child-1)/2;// compare with value at parent and swap if parent

smallerif (comp.compare(data.get(parent), data.get(child))

< 0) {swap(data, child, parent);pushup(parent);

}}

private void swap(List<E> data, int from, int to)data.set(child, data.set(parent, data.get(child)));

Bee35

Eel26

Kea19

Dog14

Fox7

Ant9

Hen23

Gnu13

Jay1

Tui22

0 1 3 7 8 942 65

recurse up the tree...

Page 19: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

19

HeapQueue: pushdownprivate void pushdown(int parent) {

int largeCh = 2*parent+1;int otherCh = largeCh+1;

// check if any childrenif (largeCh >= data.size()) return;

// find largest child if (otherCh < data.size() &&

comp.compare(data.get(largeCh), data.get(otherCh)) < 0 )largeCh = otherCh;

// compare with largest child, and swap if smallerif (comp.compare(data.get(parent), data.get(largeCh)) < 0) {

swap(data, largeCh, parent);pushdown(largeCh);

}

} Cat4

Eel26

Kea19

Dog14

Fox7

Ant9

Hen23

Gnu13

Jay1

0 1 3 7 8 942 65recurse down the tree...

Page 20: COMP 103 Priority Queues, Partially Ordered Trees and Heaps.

20

HeapQueue: Analysis Cost of offer:

= cost of pushup= O(log(n))

log(n) comparisons, 2 log(n) assignments

Cost of poll: = cost of pushdown= O(log(n))

2 log(n) comparisons, 2 log(n) assignments

Conclusion: HeapQueue is always fast!!