Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
MIPS Assembly:
Quicksort
CptS 260Introduction to Computer Architecture
Week 4.1Mon 2014/06/30
This Week
• 06/30 Mon Quicksort (overview)
• 07/01 Tue Quicksort (partition, HW6)
• 07/02 Wed Review– HW1 – HW5 Topics– MIPS Simple Datapath– MIPS Assembly
• Stack frame• Function calling functions
• 07/03 Thu Midterm Exam– In class– Closed book (MIPS reference card will be attached)
Quicksort
• Yet Another Sorting Algorithm– Hoare 1960
• “Best” average-case performance!– Best case ~ O( n log n)– On average, 1.39 × best-case– worst-case ~ O(n2)
• Online Resources– Wikipedia, “Quicksort”, Repeated elements– www.sorting-algorithms.com/quick-sort-3-way
Quicksort: Implementation Overview
• A Confluence of “Big Concepts”– Array (of integers)– Pointers (to integer)– Recursion– MIPS multiple return values: $v0, $v1
• Divide and Conquer– Works for any array sequence!
3 7 8 5 2 1 9 5 4A:
begin end
QUICKSORT( begin, end ){
if (begin >= end) return;p = PARTITION( begin, end );QUICKSORT ( begin, p );QUICKSORT ( p + 1, end );
}
DIVIDE-AND-CONQUER( b, e ){
if (b >= e) return;p = SPLIT ( b, e );DIVIDE-AND-CONQUER ( b, p );DIVIDE-AND-CONQUER ( p + 1, e );
}
First Hurdle: HW Interface and Conversions
• The HW Interface is Non-Negotiable– Heed the HW PDFs!!– Heed all MIPS conventions: $a*, $v*
� You May Make Your OwnInternal (Private) Interface
�You Do The Conversion!
Grading Harness
test_n
∀ t:
HW PDF
$a0: int A[]$a1: int len
$a0: int * lo = …$a1: int * hi = …
3 7 8 5 2 1 9 5 4A:
Partition in Set Theory
• Set Theory / Ontology– A disjoint covering
• Computer Science (algorithm)– Given A set S– and predicate P (function that returns true or false)
partition( S, P) = Strue Sfalse rearranges elementsreturns: the midpoint ↑
HW6: Outline of Tasks quicksort ( a0: int A[], a1: int len )
your adapter here …
// returns nothingswap ( a0: int *, a1: int *)
// exchanges *a0 and *a1
// returns $v0 == end of S =
partition( a0: word * lo, a1: word * hi )
{ … }
// returns $v0 == start of S =
// and $v1 == start of S >=
enlarge ( a0: int * mid ){ … }
quicksort_ab ( a0: …, a1: … )
{ … }
Quicksort: Three-Way (“Fat”) Partition
• HW6 Requirements– Partition handles base cases– Two return values: $v0, $v1
• Many partition algorithms– One write pointer (Wikipedia)
– Two-pointer swap
– Two write pointers
– Your Idea Here …
Wikipedia:One read “pointer”, One write “pointer”• http://en.wikipedia.org/wiki/Quicksort , In-place version
// Returns the pivot indexint partition(A, left, right)
int pivot := A[right]// Move pivot to end// swap A[pi], A[right]
int wr := leftfor i = left to right – 1
if A[i] <= pivotswap A[i], A[wr]++wr
// Move pivot to middleswap A[wr], A[right]return wr
3 7 8 5 2 1 9 5 4
i
wr
left right
Three-Way Partition using Two -Pointer Swap:Swapping the Pivot
while (lo < hi){
// seek leftwhile (*lo <= pivot) ++lo;// seek rightwhile (*hi >= pivot) ––hi;// exchangeswap (lo++, hi ––);
}// move pivot to end of S =
swap(last, lo);
3 7 8 5 2 1 9 5
lo hi
4
1 7
2 8
3 1 2 5 8 7 9 5 4
brute{sort,part}.asm – Output
brutesort.asm – Pretty Printing
void endl (void) # print_char(‘\n’)
void print_int ($a0 : a) # “a ” (with trailing space)
void print_array_int # “a0 a1 … ae ” (with trailing space)($a0 = int A[], $a1 = int * E) # in half-open interval [A, E)
void print_array_withz # “a0 … ae | z0 … ze \n”( $a0 = int A[], $a1 = int len, $a2 = int lenz)
lenlenz
void brutesort_ettu # struct TestCase { int len; int A[]; };($a0 = TestCase * T) # prints T–>A[] (before)
# quicksort(T–>len, T–>A[])# prints T–>A[] (after)
Swapping the Pivot:Enumerating Some Cases
• Contributing factors (?):– Array parity: even odd– Middle element (if odd) < p ==p > p– Degenerate cases: lo-fails hi-fails
Swapping the Pivot:Ascending, Descending
oddeven
1 2 3 5 6
lo
hi
4 1 2 5 6
lo
hi
4
swap to
swap(last, lo );
6 8 9 2 1 4 6 8 2 1 4
Ascending
Descending
Swapping the Pivot:One Pointer Fails
oddeven
1 2 3 2 1
lo
hi
4 1 2 3 2
lo
hi
4
swap to
lo-fails
9 8 7 5 6
lo
hi
4 8 8 5 6
lo
hi
4hi-fails
1 n# 3-way partitioni = 1, k = 1, p = n
while i < pif A[i] < A[n] swap A[i++, k++]
else if A[i] == A[n] swap A[i, --p]else i++
end→ invariant: A[p .. n] all equal→ invariant:
A[1..k-1] < A[p .. n] < A[k..p-1]
# move pivots to centerm = min(p-k, n-p+1)swap A[k .. k+m-1, n-m+1 .. n]
# recursive sortssort A[1, k-1]sort A[n-p+k+1, n]
3-Way Partition:Two Write Pointers
• www.sorting-algorithms.com/quick-sort-3-way– Pascal-like array notation: [1 .. n]
# choose pivot# swap A[n, rand(1,n)]
i
k p3 4 7 8 5 2 4 1 9 5 4 4
1 n# 3-way partitioni = 1, k = 1, p = n
while i < pif A[i] < A[n] swap A[i++, k++]
else if A[i] == A[n] swap A[i, --p]else i++
end→ invariant: A[p .. n] all equal→ invariant:
A[1..k-1] < A[p .. n] < A[k..p-1]
# move pivots to centerm = min(p-k, n-p+1)swap A[k .. k+m-1, n-m+1 .. n]
# recursive sortssort A[1, k-1]sort A[n-p+k+1, n]
3-Way Partition:Two Write Pointers
i
k p3 4 7 8 5 2 4 1 9 5 4 4
1 n# 3-way partitioni = 1, k = 1, p = n
while i < pif A[i] < A[n] swap A[i++, k++]
else if A[i] == A[n] swap A[i, --p]else i++
end→ invariant: A[p .. n] all equal→ invariant:
A[1..k-1] < A[p .. n] < A[k..p-1]
# move pivots to centerm = min(p-k, n-p+1)swap A[k .. k+m-1, n-m+1 .. n]
# recursive sortssort A[1, k-1]sort A[n-p+k+1, n]
3-Way Partition:Two Write Pointers
i
k p3 4 7 8 5 2 4 1 9 5 4 4
4
4
5
4
1 n# 3-way partitioni = 1, k = 1, p = n
while i < pif A[i] < A[n] swap A[i++, k++]
else if A[i] == A[n] swap A[i, --p]else i++
end→ invariant: A[p .. n] all equal→ invariant:
A[1..k-1] < A[p .. n] < A[k..p-1]
# move pivots to centerm = min(p-k, n-p+1)swap A[k .. k+m-1, n-m+1 .. n]
# recursive sortssort A[1, k-1]sort A[n-p+k+1, n]
3-Way Partition:Two Write Pointers
i
k p3 5 7 8 5 2 4 1 9 4 4 4
i
k p3 4 7 8 5 2 4 1 9 5 4 4
4
4
5
4
1 n# 3-way partitioni = 1, k = 1, p = n
while i < pif A[i] < A[n] swap A[i++, k++]
else if A[i] == A[n] swap A[i, --p]else i++
end→ invariant: A[p .. n] all equal→ invariant:
A[1..k-1] < A[p .. n] < A[k..p-1]
# move pivots to centerm = min(p-k, n-p+1)swap A[k .. k+m-1, n-m+1 .. n]
# recursive sortssort A[1, k-1]sort A[n-p+k+1, n]
3-Way Partition:Two Write Pointers
i
k p3 5 7 8 5 2 4 1 9 4 4 4
2 4
5 9 7
1
i
k p3 2 1 8 5 5 9 7 4 4 4 4
1 n# 3-way partitioni = 1, k = 1, p = n
while i < pif A[i] < A[n] swap A[i++, k++]
else if A[i] == A[n] swap A[i, --p]else i++
end→ invariant: A[p .. n] all equal→ invariant:
A[1..k-1] < A[p .. n] < A[k..p-1]
# move pivots to centerm = min(p-k, n-p+1)swap A[k .. k+m-1, n-m+1 .. n]
# recursive sortssort A[1, k-1] # A[01, 03]sort A[n-p+k+1, n] # A[08, 12]
3-Way Partition:Two Write Pointers
i
k p
3 2 1 8 5 5 9 7 4 4 4 4
# min(12 – 4, 12 – 8 + 1) = 5# A[4 .. 8, 8 .. 12]
3 2 1 4 4 4 4 7 9 5 5 8
3 4 7 8 5 2 4 1 9 5 4 4
$v0 $v1