Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our...

32

Transcript of Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our...

Page 1: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented
Page 2: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Heaps, stacks, queuesDan S. Wallach and Mack Joyner, Rice University

Copyright © 2016 Dan Wallach, All Rights Reserved

Page 3: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Where was Prof. Wallach on Tuesday?

Page 4: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Two hours of scintillating Congressional testimony: https://www.youtube.com/watch?v=iRU9ZuFF9a0

Page 5: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Two hours of scintillating Congressional testimony: https://www.youtube.com/watch?v=iRU9ZuFF9a0

At the end of th

e semester, if

we have time, w

e’ll have a

lecture on computer security

& electronic vo

ting.

Page 6: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Preliminaries: queues vs. stacks

Stack: last-in-first-out (LIFO) Our IList classes work like this.

Queue: first-in-first-out (FIFO) You implemented this last week.

Functional vs. mutating? Straightforward to do it either way.

Page 7: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

How do you implement a mutating queue?

Option 1: doubly-linked list (java.util.LinkedList) Every node has pointers to next and previous nodes “Sentinel” node to deal with empty-list case O(1) insert and removal Possible to add and remove from either end (= Deque or Dequeue)

Option 2: array (java.util.ArrayDeque) Tricky: requires growing the array, tracking start/end, wraparound O(1) insert and removal (amortized: sometimes requires an O(n) copy)

Page 8: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

How about a functional queue?

Option 1: use two lists (“inbox” and “outbox”) You built this last week. Constant amortized time.

Option 2: use a tree (not recommended) You’ll notice that our trees have a “getMin” method. All operations are O(log n)

Page 9: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

So what’s a priority queue?

Priority queues are typically implemented via mutation.

getMin() returns the smallest value and removes it at the same time. public interface IPriorityQueue<T> { T getMin(); void insert(T val); int size(); boolean empty(); }

Page 10: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: efficient priority queuesStorage happens in an array (or java.util.ArrayList)

Map a tree into the array. No pointers, just math on array indices. leftChild(i) = 2i + 1 rightChild(i) = 2i + 2 parent(i) = (i-1)/2 Note: integer arithmetic

2 4 3 7 9 6 5 110 1 2 3 4 5 6 7

2

4

7 9

3

6 5

11

0

1 2

3 4 5 6

7 A tree like this is called “complete”.

Heap values

Array index

Page 11: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: data definition“The heap property”: A parent’s value is less than (or equal to) its children’s values.

Ergo: The minimum value is in the root. And that’s the zeroth element.

2

4

7 9

3

6 5

11

0

1 2

3 4 5 6

7 A tree like this is called “complete”.

Heap values

Array index2 4 3 7 9 6 5 110 1 2 3 4 5 6 7

Page 12: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: inserting a new valueFirst, go to the next available slot (here, #8) Work upwards, swapping to create the heap property

insert(3)

2

4

7 9

3

6 5

0

1 2

4 5 6

117

3

Page 13: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: inserting a new valueFirst, go to the next available slot (here, #8) Work upwards, swapping to create the heap property

insert(3)

2

4

7 9

3

6 5

0

1 2

4 5 6

117 3 8

3

Page 14: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: inserting a new valueFirst, go to the next available slot (here, #8) Work upwards, swapping to create the heap property

insert(3)

2

4

7 9

3

6 5

0

1 2

4 5 6

117 3 8

3

Page 15: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: inserting a new valueFirst, go to the next available slot (here, #8) Work upwards, swapping to create the heap property

insert(3)

2

4

3 9

3

6 5

0

1 2

4 5 6

117 7 8

3

Page 16: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: inserting a new valueFirst, go to the next available slot (here, #8) Work upwards, swapping to create the heap property

insert(3)

2

4

3 9

3

6 5

0

1 2

4 5 6

117 7 8

3

Page 17: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: inserting a new valueFirst, go to the next available slot (here, #8) Work upwards, swapping to create the heap property

insert(3)

2

3

4 9

3

6 5

0

1 2

4 5 6

117 7 8

3

Page 18: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: inserting a new valueFirst, go to the next available slot (here, #8) Work upwards, swapping to create the heap property

insert(3)

2

3

4 9

3

6 5

0

1 2

4 5 6

117 7 8

3

Page 19: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: inserting a new valueFirst, go to the next available slot (here, #8) Work upwards, swapping to create the heap property

insert(3) Insertion cost: O(log n) Stable, predictable.

2

3

4 9

3

6 5

0

1 2

4 5 6

117 7 8

3

Page 20: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

First, move the last child to the top.

2

3

4 9

3

6 5

0

1 2

4 5 6

117 7 8

3

Page 21: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

First, move the last child to the top.

2

3

4 9

3

6 5

0

1 2

4 5 6

117 7 8

3

Page 22: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

Now recursively work down Reestablish the “heap property”. Use the smallest value. If equal, either is fine.

7

3

4 9

3

6 5

0

1 2

4 5 6

117

3

Page 23: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

Now recursively work down Reestablish the “heap property”. Use the smallest value. If equal, either is fine.

7

3

4 9

3

6 5

0

1 2

4 5 6

117

3

Page 24: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

Now recursively work down Reestablish the “heap property”. Use the smallest value. If equal, either is fine.

3

7

4 9

3

6 5

0

1 2

4 5 6

117

3

Page 25: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

Now recursively work down Reestablish the “heap property”. Use the smallest value. If equal, either is fine.

3

7

4 9

3

6 5

0

1 2

4 5 6

117

3

Page 26: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

Now recursively work down Reestablish the “heap property”. Use the smallest value. If equal, either is fine.

3

4

7 9

3

6 5

0

1 2

4 5 6

117

3

Page 27: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

Now recursively work down Reestablish the “heap property”. Use the smallest value. If equal, either is fine.

3

4

7 9

3

6 5

0

1 2

4 5 6

117

3

Page 28: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Binary heaps: removing the min valueThe answer is right on top, so that’s easy But what about the children?

Now recursively work down Reestablish the “heap property”. Use the smallest value. If equal, either is fine.

Total cost: O(log n)

3

4

7 9

3

6 5

0

1 2

4 5 6

117

3

Page 29: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Using arrays is a serious win

Compact memory usage (no left/right pointers)

Navigating up or down is easy

O(log n) operations aren’t just “expected case” A heap is always a “complete tree”, so it’s always O(log n)

ArrayList vs. arrays ArrayList will automatically allocate bigger arrays (internally) and copy.

Page 30: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Performance numbers

FIFO queues (functional) ListQueue : 1000000 inserts, 10000 fetches: 0.170 μs per insert TreapQueue : 1000000 inserts, 10000 fetches: 0.387 μs per insert FIFO queues (mutating) LinkedList : 1000000 inserts, 10000 fetches: 0.020 μs per insert ArrayDeque : 1000000 inserts, 10000 fetches: 0.018 μs per insert

Priority queues (mutating) BinaryHeap : 1000000 inserts, 10000 fetches: 0.099 μs per insert PriorityQueue: 1000000 inserts, 10000 fetches: 0.061 μs per insert

Page 31: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Performance numbers

FIFO queues (functional) ListQueue : 1000000 inserts, 10000 fetches: 0.170 μs per insert TreapQueue : 1000000 inserts, 10000 fetches: 0.387 μs per insert FIFO queues (mutating) LinkedList : 1000000 inserts, 10000 fetches: 0.020 μs per insert ArrayDeque : 1000000 inserts, 10000 fetches: 0.018 μs per insert

Priority queues (mutating) BinaryHeap : 1000000 inserts, 10000 fetches: 0.099 μs per insert PriorityQueue: 1000000 inserts, 10000 fetches: 0.061 μs per insert

Mutation is winning big, this time...

Page 32: Heaps, stacks, queues€¦ · Preliminaries: queues vs. stacks Stack: last-in-first-out (LIFO) Our IList classes work like this. Queue: first-in-first-out (FIFO) You implemented

Live coding

Q&A for project 4

Advice for debugging Build your valid() method first, then use it to test. Take advantage of printing your treaps. Use toStringHelper().