---
template: templates/cse250_2022_slides.erb
title: Graph Exploration
date: Oct 14, 2022
textbookTBD: Ch. 15.3
cat: graphics/19b/cat.png
---
An ordering $(A, \leq)$ (an ordering over type $A$) is ... An ordering needs to be... Course 1 $\leq$ Course 2 iff Course 1 is a prereq of Course 2 Is this a valid ordering? Yes! (Partial order, as opposed to Total order) A partial ordering needs to be... A total ordering needs to be... For a sort order $(A, \leq)$ A partial order may not have a unique greatest/least element $\leq$ can be described explicitly, by a set of tuples. If $(x, y)$ is in the set, $x \leq y$ $\leq$ can be described by a mathematical rule. $x \leq y$ iff $x, y$ are integers, and there is a non-negative integer $a$ s.t. $x + a = y$ Multiple orderings can be defined for the same set. We use a subscripts to separate orderings (e.g., $\leq_1$, $\leq_2$, $\leq_3$) 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$
Examples
Ordering
Ordering Properties
Ordering Properties
Ordering Properties
Ordering Properties
Ordering Properties
(Partial)Ordering Properties
(Total)Ordering Properties
Formally...
Formally...
Formally...
Formally...
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.
A Topological Sort $(A, \leq_2)$ is any total order over $x$ that "agrees" with a partial order $(A, \leq_1)$
For any two elements $x, y \in X$:
The following are all topological sorts over our partial order example:
(If the partial order is a schedule requirement, each topological sort is a possible schedule)
And now, for an ordering-based ADT...
How do we store these items?
5, 9, 2, 7?
9, 7, 5, 2?
2, 5, 7, 9?
Base Data Structure: Linked List
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
}
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] | () |
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?
Base Data Structure: Linked List
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] | () |
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?
Operation | Lazy | Proactive |
---|---|---|
enqueue | $O(1)$ | $O(n)$ |
dequeue | $O(n)$ | $O(1)$ |
head | $O(n)$ | $O(1)$ |
Can we do better?