CSE-250 Fall 2022 - Section B - Orderings, Priority Queues

Orderings, Priority Queues

CSE-250 Fall 2022 - Section B

Oct 14, 2022

Textbook: Ch. 13.1

Examples

  • $(B, 10)$, $(D, 3)$, $(E, 40)$
  • ā€œA+ā€, ā€œCā€, ā€œB-ā€
  • Taco Tuesday, Fish Friday, Meatless Monday
  • The Princess Bride, Crouching Tiger Hidden Dragon, Rob Roy
  • Aardvark, Baboon, Capybara, Donkey, Echidna, ...

Ordering

An ordering $(A, \leq)$ (an ordering over type $A$) is ...

  • A collection (set) of things of type $A$
  • A "relation" or comparator $\leq$ that relates two things
$5 \leq 30 \leq 999$
Numerical order
$(E, 40) \leq (B, 10) \leq (D, 3)$
Reverse-numerical order on the 2nd field
$C+ \leq B- \leq B \leq B+ \leq A- \leq A$
Letter grades
$AA \leq AM \leq BZ \leq CA \leq CD$
Compare 1st letter, if same compare 2nd, if same compare 3rd, ... ("Lexical Order")

Ordering Properties

Crouching Tiger Hidden Dragon $\leq$ Princess Bride
Carey Elwes and Mandy Patankin have amazing banter
Princess Bride $\leq$ Rob Roy
Rob Roy: Best climactic duel of all time
Rob Roy $\leq$ Crouching Tiger Hidden Dragon
A ton of amazingly technical fights

Ordering Properties

Ordering Properties

An ordering needs to be...

Reflexive
$x \leq x$
Antisymmetric
If $x \leq y$ and $y \leq x$ then $x = y$
Transitive
If $x \leq y$ and $y \leq z$ then $x \leq z$

Ordering Properties

Course 1 $\leq$ Course 2 iff Course 1 is a prereq of Course 2

  • CSE 115 $\leq$ CSE 116
  • CSE 116 $\leq$ CSE 250
  • CSE 115 $\leq$ CSE 191
  • CSE 191 $\leq$ CSE 250

Ordering Properties

Is this a valid ordering?

Yes!

(Partial order, as opposed to Total order)

(Partial)Ordering Properties

A partial ordering needs to be...

Reflexive
$x \leq x$
Antisymmetric
If $x \leq y$ and $y \leq x$ then $x = y$
Transitive
If $x \leq y$ and $y \leq z$ then $x \leq z$

(Total)Ordering Properties

A total ordering needs to be...

Reflexive
$x \leq x$
Antisymmetric
If $x \leq y$ and $y \leq x$ then $x = y$
Transitive
If $x \leq y$ and $y \leq z$ then $x \leq z$
Complete
Either $x \leq y$ or $y \leq x$ for any $x, y \in A$.

Formally...

For a sort order $(A, \leq)$

Greatest
An element $x \in A$ s.t. there is no $y \in A$, where $x \leq y$
Least
An element $x \in A$ s.t. there is no $y \in A$, where $y \leq x$

A partial order may not have a unique greatest/least element

Formally...

$\leq$ can be described explicitly, by a set of tuples.

$$\{\; (a, a), (a, b), (a, c), \ldots, (b, b), \ldots, (z, z) \;\}$$

If $(x, y)$ is in the set, $x \leq y$

Formally...

$\leq$ can be described by a mathematical rule.

$$\{\; (x, y) \;|\; x, y \in \mathbb Z, \exists a \in \mathbb Z_0^{+} : x + a = y \;\}$$

$x \leq y$ iff $x, y$ are integers, and there is a non-negative integer $a$ s.t. $x + a = y$

Formally...

Multiple orderings can be defined for the same set.

  • RottenTomatoes vs Metacritic vs Box Office Gross.
  • "Best Movie" first vs "Worst Movie" first.
  • Rank by number of air ducts crawled through.

We use a subscripts to separate orderings (e.g., $\leq_1$, $\leq_2$, $\leq_3$)

Formally...

We can transform orderings.

Reverse: If $x \leq_1 y$, then define $y \leq_r x$

Lexical: Given $\leq_1, \leq_2, \leq_3, \ldots$

  • If $x \leq_1 y$ then $x \leq_\ell y$
  • If $x =_1 y$ and $x \leq_2 y$ then $x \leq_\ell y$
  • If $x =_2 y$ and $x \leq_3 y$ then $x \leq_\ell y$
  • ....

Examples of Lexical Ordering

  • Names: First letter, then second, then third...
  • Movies: Average of reviews, then number of reviews...
  • Tuples: First field, then second field, then third...

Formally...

$\leq$ can be described an ordering over a key derived from the element.

$x \leq_{edge} y$ iff $weight(x) \leq weight(y)$

$x \leq_{student} y$ iff $name(x) \leq_{lex} name(y)$

We say that the weight (resp., name) is a key.

Topological Sort

A Topological Sort of a partial order $(A, \leq_1)$ is any total order $(A, \leq_2)$ over $A$ that "agrees" with $(A, \leq_1)$

For any two elements $x, y \in A$:

  • If $x \leq_1 y$ then $x \leq_2 y$
  • If $y \leq_1 x$ then $y \leq_2 x$
  • Otherwise, either $x \leq_2 y$ or $y \leq_2 x$

Topological Sort

The following are all topological sorts over our partial order example:

  • CSE 115, CSE 116, CSE 191, CSE 241, CSE 250
  • CSE 241, CSE 115, CSE 116, CSE 191, CSE 250
  • CSE 115, CSE 191, CSE 116, CSE 250, CSE 241

(If the partial order is a schedule requirement, each topological sort is a possible schedule)

And now, for an ordering-based ADT...

Priority Queues

PriorityQueue[A <: Ordering]

enqueue(v: A): Unit
Insert a value $v$ into the priority queue.
dequeue: A
Remove the greatest element in the priority queue.
head: A
Peek at the greatest element in the priority queue.
  • enqueue(5)
  • enqueue(9)
  • enqueue(2)
  • enqueue(7)
  • head ā†’ 9
  • dequeue ā†’ 9
  • size ā†’ 3
  • head ā†’ 7
  • dequeue ā†’ 7
  • dequeue ā†’ 5
  • dequeue ā†’ 2
  • isEmpty ā†’ true

How do we store these items?

5, 9, 2, 7?

9, 7, 5, 2?

2, 5, 7, 9?

Two mentalities...

Lazy: Keep everything in a mess
"Selection Sort"
Proactive: Keep everything organized
"Insertion Sort"

Lazy Priority Queue

Base Data Structure: Linked List

enqueue(t:A)
Append $t$ to the end of the linked list. $O(1)$
head/dequeue
Traverse the list to find the largest value. $O(n)$

Sort


  def pqueueSort[A](items: Seq[A], pqueue: PriorityQueue[A]): Seq[A] =
  {
    val out = new Array[A](items.size)
    for(item <- items){ pqueue.enqueue(item) }
    i = out.size - 1
    while(!pqueue.isEmpty) { buffer(i) = pqueue.dequeue; i-- }
    return out.toSeq
  }
  

Selection Sort

Seq/Buffer PQueue
Input (7, 4, 8, 2, 5, 3, 9) ()
Step 1 (4, 8, 2, 5, 3, 9) (7)
Step 2 (8, 2, 5, 3, 9) (7, 4)
į§ į§ į§
Step N [_, _, _, _, _, _, _] (7, 4, 8, 2, 5, 3, 9)
Step N+1 [_, _, _, _, _, _, 9] (7, 4, 8, 2, 5, 3)
Step N+2 [_, _, _, _, _, 8, 9] (7, 4, 2, 5, 3)
Step N+3 [_, _, _, _, 7, 8, 9] (4, 2, 5, 3)
Step N+4 [_, _, _, 5, 7, 8, 9] (4, 2, 3)
Step N+5 [_, _, 4, 5, 7, 8, 9] (2, 3)
Step N+6 [_, 3, 4, 5, 7, 8, 9] (2)
Step 2N [2, 3, 4, 5, 7, 8, 9] ()

Selection Sort


  def pqueueSort[A](items: Seq[A], pqueue: PriorityQueue[A]): Seq[A] =
  {
    val out = new Array[A](items.size)
    for(item <- items){ pqueue.enqueue(item) }
    i = out.size - 1
    while(!pqueue.isEmpty) { buffer(i) = pqueue.dequeue; i-- }
    return out.toSeq
  }
  

What's the complexity?

Proactive Priority Queue

Base Data Structure: Linked List

enqueue(t:A)
Find $t$'s position in reverse sorted order. $O(n)$
head/dequeue
Refer to the head item in the list. $O(1)$

Insertion Sort

Seq/Buffer PQueue
Input (7, 4, 8, 2, 5, 3, 9) ()
Step 1 (4, 8, 2, 5, 3, 9) (7)
Step 2 (8, 2, 5, 3, 9) (7, 4)
Step 3 (2, 5, 3, 9) (8, 7, 4)
Step 4 (5, 3, 9) (8, 7, 4, 2)
Step 5 (3, 9) (8, 7, 5, 4, 2)
Step 6 (9) (8, 7, 5, 4, 3, 2)
Step N [_, _, _, _, _, _, _] (9, 8, 7, 5, 4, 3, 2)
Step N+1 [_, _, _, _, _, _, 9] (8, 7, 5, 4, 3, 2)
į§ į§ į§
Step 2N [2, 3, 4, 5, 7, 8, 9] ()

Insertion Sort


  def pqueueSort[A](items: Seq[A], pqueue: PriorityQueue[A]): Seq[A] =
  {
    val out = new Array[A](items.size)
    for(item <- items){ pqueue.enqueue(item) }
    i = out.size - 1
    while(!pqueue.isEmpty) { buffer(i) = pqueue.dequeue; i-- }
    return out.toSeq
  }
  

What's the complexity?

Priority Queues

Operation Lazy Proactive
enqueue $O(1)$ $O(n)$
dequeue $O(n)$ $O(1)$
head $O(n)$ $O(1)$

Can we do better?