2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,19 +1,32 @@
{{Sorting Algorithm}}[[Category:Recursion]]
{{wikipedia|Quicksort}}
{{Sorting Algorithm}}
[[Category:Recursion]]
{{Wikipedia|Quicksort}}
The task is to sort an array (or list) elements using the ''quicksort'' algorithm.
The elements must have a strict weak order and the index of the array can be of any discrete type. For languages where this is not possible, sort an array of integers.
Quicksort, also known as ''partition-exchange sort'', uses these steps.
;Task:
Sort an array (or list) elements using the   [https://en.wikipedia.org/wiki/Quicksort ''quicksort'']   algorithm.
# Choose any element of the array to be the pivot.
# Divide all other elements (except the pivot) into two partitions.
#* All elements less than the pivot must be in the first partition.
#* All elements greater than the pivot must be in the second partition.
# Use recursion to sort both partitions.
# Join the first sorted partition, the pivot, and the second sorted partition.
The elements must have a   [https://en.wikipedia.org/wiki/Weak_ordering strict weak order]   and the index of the array can be of any discrete type.
For languages where this is not possible, sort an array of integers.
Quicksort, also known as   ''partition-exchange sort'',   uses these steps.
::#   Choose any element of the array to be the pivot.
::#   Divide all other elements (except the pivot) into two partitions.
::#*   All elements less than the pivot must be in the first partition.
::#*   All elements greater than the pivot must be in the second partition.
::#   Use recursion to sort both partitions.
::#   Join the first sorted partition, the pivot, and the second sorted partition.
<br>
The best pivot creates partitions of equal length (or lengths differing by &nbsp; '''1''').
The worst pivot creates an empty partition (for example, if the pivot is the first or last element of a sorted array).
The run-time of Quicksort ranges from &nbsp; <big> ''[[O]](n ''log'' n)'' </big> &nbsp; with the best pivots, to &nbsp; <big> ''[[O]](n<sup>2</sup>)'' </big> &nbsp; with the worst pivots, where &nbsp; <big> ''n'' </big> &nbsp; is the number of elements in the array.
The best pivot creates partitions of equal length (or lengths differing by 1). The worst pivot creates an empty partition (for example, if the pivot is the first or last element of a sorted array). The runtime of Quicksort ranges from ''[[O]](n ''log'' n)'' with the best pivots, to ''[[O]](n<sup>2</sup>)'' with the worst pivots, where ''n'' is the number of elements in the array.
This is a simple quicksort algorithm, adapted from Wikipedia.
@ -48,7 +61,7 @@ A better quicksort algorithm works in place, by swapping elements within the arr
quicksort(array '''from first index to''' right)
quicksort(array '''from''' left '''to last index''')
Quicksort has a reputation as the fastest sort. Optimized variants of quicksort are common features of many languages and libraries. One often contrasts quicksort with [[../Merge sort|merge sort]], because both sorts have an average time of ''[[O]](n ''log'' n)''.
Quicksort has a reputation as the fastest sort. Optimized variants of quicksort are common features of many languages and libraries. One often contrasts quicksort with &nbsp; [[../Merge sort|merge sort]], &nbsp; because both sorts have an average time of &nbsp; <big> ''[[O]](n ''log'' n)''. </big>
: ''"On average, mergesort does fewer comparisons than quicksort, so it may be better when complicated comparison routines are used. Mergesort also takes advantage of pre-existing order, so it would be favored for using sort() to merge several sorted arrays. On the other hand, quicksort is often faster for small arrays, and on arrays of a few distinct values, repeated many times."'' — http://perldoc.perl.org/sort.html
@ -57,6 +70,8 @@ Quicksort is at one end of the spectrum of divide-and-conquer algorithms, with m
* Quicksort is a conquer-then-divide algorithm, which does most of the work during the partitioning and the recursive calls. The subsequent reassembly of the sorted partitions involves trivial effort.
* Merge sort is a divide-then-conquer algorithm. The partioning happens in a trivial way, by splitting the input array in half. Most of the work happens during the recursive calls and the merge phase.
<br>
With quicksort, every element in the first partition is less than or equal to every element in the second partition. Therefore, the merge phase of quicksort is so trivial that it needs no mention!
This task has not specified whether to allocate new arrays, or sort in place. This task also has not specified how to choose the pivot element. (Common ways to are to choose the first element, the middle element, or the median of three elements.) Thus there is a variety among the following implementations.
<br><br>

View file

@ -1,11 +1,16 @@
* quicksort 14/09/2015
* Quicksort 14/09/2015 & 23/06/2016
QUICKSOR CSECT
USING QUICKSOR,R15 set base register
BEGIN MVC A,=F'1' a(1)=1
MVC B,=A((A-T)/4) b(1)=hbound(t)
USING QUICKSOR,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
STM R14,R12,12(R13) prolog
ST R13,4(R15) "
ST R15,8(R13) "
LR R13,R15 "
MVC A,=A(1) a(1)=1
MVC B,=A(NN) b(1)=hbound(t)
L R6,=F'1' k=1
WHILEK LTR R6,R6 do while k^=0
BZ EWHILEK
DO WHILE=(LTR,R6,NZ,R6) do while k<>0 ==================
LR R1,R6 k
SLA R1,2 ~
L R10,A-4(R1) l=a(k)
@ -15,7 +20,7 @@ WHILEK LTR R6,R6 do while k^=0
BCTR R6,0 k=k-1
LR R4,R11 m
C R4,=F'2' if m<2
BL WHILEK then iterate
BL ITERATE then iterate
LR R2,R10 l
AR R2,R11 +m
BCTR R2,0 -1
@ -33,74 +38,72 @@ WHILEK LTR R6,R6 do while k^=0
LR R1,R10 l
SLA R1,2 ~
L R3,T-4(R1) r3=t(l)
IF CR R4,R3 if t(x)<t(l)
BNL ELSE
CR R5,R4 if t(y)<t(x)
BNL IFX
LR R7,R4 p=t(x)
L R1,X x
SLA R1,2 ~
ST R3,T-4(R1) t(x)=t(l)
B EIFX
IFX CR R5,R3 if t(y)>t(l)
BNH IFXELIF
LR R7,R3 p=t(l)
B EIFX
IFXELIF LR R7,R5 p=t(y)
L R1,Y y
SLA R1,2 ~
ST R3,T-4(R1) t(y)=t(l)
EIFX B ENDIF
ELSE CR R5,R3 if t(y)<t(l)
BNL IFY
LR R7,R3 p=t(l)
B ENDIF
IFY CR R5,R4 if t(y)>t(x)
BNH IFYELIF
LR R7,R4 p=t(x)
L R1,X x
SLA R1,2 ~
ST R3,T-4(R1) t(x)=t(l)
B ENDIF
IFYELIF LR R7,R5 p=t(y)
L R1,Y y
SLA R1,2 ~
ST R3,T-4(R1) t(y)=t(l)
ENDIF LA R8,1(R10) i=l+1
IF CR,R4,LT,R3 if t(x)<t(l) ---+
IF CR,R5,LT,R4 if t(y)<t(x) |
LR R7,R4 p=t(x) |
L R1,X x |
SLA R1,2 ~ |
ST R3,T-4(R1) t(x)=t(l) |
ELSEIF CR,R5,GT,R3 elseif t(y)>t(l) |
LR R7,R3 p=t(l) |
ELSE , else |
LR R7,R5 p=t(y) |
L R1,Y y |
SLA R1,2 ~ |
ST R3,T-4(R1) t(y)=t(l) |
ENDIF , end if |
ELSE , else |
IF CR,R5,LT,R3 if t(y)<t(l) |
LR R7,R3 p=t(l) |
ELSEIF CR,R5,GT,R4 elseif t(y)>t(x) |
LR R7,R4 p=t(x) |
L R1,X x |
SLA R1,2 ~ |
ST R3,T-4(R1) t(x)=t(l) |
ELSE , else |
LR R7,R5 p=t(y) |
L R1,Y y |
SLA R1,2 ~ |
ST R3,T-4(R1) t(y)=t(l) |
ENDIF , end if |
ENDIF , end if ---+
LA R8,1(R10) i=l+1
L R9,X j=x
FOREVER EQU *
LOOPWI CR R8,R9 i<=j
BH ELOOPWI
LR R1,R8 i
SLA R1,2 ~
L R2,T-4(R1) t(i)
CR R2,R7 t(i)<=p
BH ELOOPWI
LA R8,1(R8) i=i+1
B LOOPWI
ELOOPWI EQU *
LOOPWJ CR R8,R9 i<j
BNL ELOOPWJ
LR R1,R9 j
SLA R1,2 ~
L R2,T-4(R1) t(j)
CR R2,R7 t(j)>=p
BL ELOOPWJ
BCTR R9,0 j=j-1
B LOOPWJ
ELOOPWJ CR R8,R9 if i>=j
BNL EFOREVER then leave segment finished
LR R1,R8 i
SLA R1,2 ~
LA R2,T-4(R1) @t(i)
LR R1,R9 j
SLA R1,2 ~
LA R3,T-4(R1) @t(j)
L R0,0(R2) w=t(i)
MVC 0(4,R2),0(R3) t(i)=t(j) swap t(i),t(j)
ST R0,0(R3) t(j)=w
B FOREVER
EFOREVER LR R9,R8 j=i
FOREVER EQU * do forever --------------------+
LR R1,R8 i |
SLA R1,2 ~ |
LA R2,T-4(R1) @t(i) |
L R0,0(R2) t(i) |
DO WHILE=(CR,R8,LE,R9,AND, while i<=j and ---+ | X
CR,R0,LE,R7) t(i)<=p | |
AH R8,=H'1' i=i+1 | |
AH R2,=H'4' @t(i) | |
L R0,0(R2) t(i) | |
ENDDO , end while ---+ |
LR R1,R9 j |
SLA R1,2 ~ |
LA R2,T-4(R1) @t(j) |
L R0,0(R2) t(j) |
DO WHILE=(CR,R8,LT,R9,AND, while i<j and ---+ | X
CR,R0,GE,R7) t(j)>=p | |
SH R9,=H'1' j=j-1 | |
SH R2,=H'4' @t(j) | |
L R0,0(R2) t(j) | |
ENDDO , end while ---+ |
CR R8,R9 if i>=j |
BNL LEAVE then leave (segment finished) |
LR R1,R8 i |
SLA R1,2 ~ |
LA R2,T-4(R1) @t(i) |
LR R1,R9 j |
SLA R1,2 ~ |
LA R3,T-4(R1) @t(j) |
L R0,0(R2) w=t(i) + |
MVC 0(4,R2),0(R3) t(i)=t(j) |swap t(i),t(j) |
ST R0,0(R3) t(j)=w + |
B FOREVER end do forever ----------------+
LEAVE EQU *
LR R9,R8 j=i
BCTR R9,0 j=i-1
LR R1,R9 j
SLA R1,2 ~
@ -115,47 +118,52 @@ EFOREVER LR R9,R8 j=i
SLA R1,2 ~
LA R4,A-4(R1) r4=@a(k)
LA R5,B-4(R1) r5=@b(k)
C R8,Y if i<=y
BH IFIHY
ST R8,0(R4) a(k)=i
L R2,X x
SR R2,R8 -i
LA R2,1(R2) +1
ST R2,0(R5) b(k)=x-i+1
LA R6,1(R6) k=k+1
ST R10,4(R4) a(k)=l
LR R2,R9 j
SR R2,R10 -l
ST R2,4(R5) b(k)=j-l
B EIFIHY
IFIHY ST R10,4(R4) a(k)=l
LR R2,R9 j
SR R2,R10 -l
ST R2,0(R5) b(k)=j-l
LA R6,1(R6) k=k+1
ST R8,4(R4) a(k)=i
L R2,X x
SR R2,R8 -i
LA R2,1(R2) +1
ST R2,4(R5) b(k)=x-i+1
EIFIHY B WHILEK
EWHILEK LA R3,PG ibuffer
IF C,R8,LE,Y if i<=y ----+
ST R8,0(R4) a(k)=i |
L R2,X x |
SR R2,R8 -i |
LA R2,1(R2) +1 |
ST R2,0(R5) b(k)=x-i+1 |
LA R6,1(R6) k=k+1 |
ST R10,4(R4) a(k)=l |
LR R2,R9 j |
SR R2,R10 -l |
ST R2,4(R5) b(k)=j-l |
ELSE , else |
ST R10,4(R4) a(k)=l |
LR R2,R9 j |
SR R2,R10 -l |
ST R2,0(R5) b(k)=j-l |
LA R6,1(R6) k=k+1 |
ST R8,4(R4) a(k)=i |
L R2,X x |
SR R2,R8 -i |
LA R2,1(R2) +1 |
ST R2,4(R5) b(k)=x-i+1 |
ENDIF , end if ----+
ITERATE EQU *
ENDDO , end while =====================
* *** ********* print sorted table
LA R3,PG ibuffer
LA R4,T @t(i)
LOOPI C R4,=A(A) do i=1 to hbound(t)
BH ELOOPI
L R2,0(R4) t(i)
XDECO R2,XD edit t(i)
MVC 0(4,R3),XD+8 put in buffer
LA R3,4(R3) ibuffer=ibuffer+1
LA R4,4(R4) i=i+1
B LOOPI
ELOOPI XPRNT PG,80 print bufffer
RETURN XR R15,R15 set return code
BR R14 return to caller
DO WHILE=(C,R4,LE,=A(TEND)) do i=1 to hbound(t)
L R2,0(R4) t(i)
XDECO R2,XD edit t(i)
MVC 0(4,R3),XD+8 put in buffer
LA R3,4(R3) ibuffer=ibuffer+1
LA R4,4(R4) i=i+1
ENDDO , end do
XPRNT PG,80 print buffer
L R13,4(0,R13) epilog
LM R14,R12,12(R13) "
XR R15,R15 "
BR R14 exit
T DC F'10',F'9',F'9',F'6',F'7',F'16',F'1',F'16',F'17',F'15'
DC F'1',F'9',F'18',F'16',F'8',F'20',F'18',F'2',F'19',F'8'
A DS ((A-T)/4)F same size as T
B DS ((A-T)/4)F same size as T
TEND DS 0F
NN EQU (TEND-T)/4)
A DS (NN)F same size as T
B DS (NN)F same size as T
X DS F
Y DS F
PG DS CL80

View file

@ -0,0 +1,67 @@
-- quickSort :: (Ord a) => [a] -> [a]
on quickSort(xs)
if length of xs > 1 then
set {h, t} to uncons(xs)
-- lessOrEqual :: a -> Bool
script lessOrEqual
on lambda(x)
x h
end lambda
end script
set {less, more} to partition(lessOrEqual, t)
quickSort(less) & h & quickSort(more)
else
xs
end if
end quickSort
-- TEST
on run
quickSort([11.8, 14.1, 21.3, 8.5, 16.7, 5.7])
--> {5.7, 8.5, 11.8, 14.1, 16.7, 21.3}
end run
-- GENERIC FUNCTIONS
-- partition :: predicate -> List -> (Matches, nonMatches)
-- partition :: (a -> Bool) -> [a] -> ([a], [a])
on partition(f, xs)
tell mReturn(f)
set lst to {{}, {}}
repeat with x in xs
set v to contents of x
set end of item ((lambda(v) as integer) + 1) of lst to v
end repeat
return {item 2 of lst, item 1 of lst}
end tell
end partition
-- uncons :: [a] -> Maybe (a, [a])
on uncons(xs)
if length of xs > 0 then
{item 1 of xs, rest of xs}
else
missing value
end if
end uncons
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property lambda : f
end script
end if
end mReturn

View file

@ -0,0 +1 @@
{5.7, 8.5, 11.8, 14.1, 16.7, 21.3}

View file

@ -0,0 +1,20 @@
quick_sort(L) -> qs(L, erlang:system_info(schedulers)).
qs([],_) -> [];
qs([H|T], N) when N > 1 ->
{Parent, Ref} = {self(), make_ref()},
spawn(fun()-> Parent ! {l1, Ref, qs([E||E<-T, E<H], N-2)} end),
spawn(fun()-> Parent ! {l2, Ref, qs([E||E<-T, H =< E], N-2)} end),
{L1, L2} = receive_results(Ref, undefined, undefined),
L1 ++ [H] ++ L2;
qs([H|T],_) ->
qs([E||E<-T, E<H],0) ++ [H] ++ qs([E||E<-T, H =< E],0).
receive_results(Ref, L1, L2) ->
receive
{l1, Ref, L1R} when L2 == undefined -> receive_results(Ref, L1R, L2);
{l2, Ref, L2R} when L1 == undefined -> receive_results(Ref, L1, L2R);
{l1, Ref, L1R} -> {L1R, L2};
{l2, Ref, L2R} -> {L1, L2R}
after 5000 -> receive_results(Ref, L1, L2)
end.

View file

@ -9,15 +9,15 @@ function sort(array, less) {
function quicksort(left, right) {
if (left < right) {
var pivot = array[(left + right) / 1],
var pivot = array[left + Math.floor((right - right) / 2)],
left_new = left,
right_new = right;
do {
while (less(array[left_new], pivot) {
while (less(array[left_new], pivot)) {
left_new += 1;
}
while (less(pivot, array[right_new]) {
while (less(pivot, array[right_new])) {
right_new -= 1;
}
if (left_new <= right_new) {

View file

@ -1,10 +1,2 @@
Array.prototype.quick_sort = function () {
if (this.length < 2) { return this; }
var pivot = this[Math.round(this.length / 2)];
return this.filter(x => x < pivot)
.quick_sort()
.concat(this.filter(x => x == pivot))
.concat(this.filter(x => x > pivot).quick_sort());
};
var test_array = [10, 3, 11, 15, 19, 1];
var sorted_array = sort(test_array, function(a,b) { return a<b; });

View file

@ -0,0 +1 @@
[ 1, 3, 10, 11, 15, 19 ]

View file

@ -0,0 +1,38 @@
(function () {
'use strict';
// quickSort :: (Ord a) => [a] -> [a]
function quickSort(xs) {
if (xs.length) {
var h = xs[0],
t = xs.slice(1),
lessMore = partition(function (x) {
return x <= h;
}, t),
less = lessMore[0],
more = lessMore[1];
return [].concat.apply(
[], [quickSort(less), h, quickSort(more)]
);
} else return [];
}
// partition :: Predicate -> List -> (Matches, nonMatches)
// partition :: (a -> Bool) -> [a] -> ([a], [a])
function partition(p, xs) {
return xs.reduce(function (a, x) {
return (
a[p(x) ? 0 : 1].push(x),
a
);
}, [[], []]);
}
return quickSort([11.8, 14.1, 21.3, 8.5, 16.7, 5.7])
})();

View file

@ -0,0 +1,10 @@
Array.prototype.quick_sort = function () {
if (this.length < 2) { return this; }
var pivot = this[Math.round(this.length / 2)];
return this.filter(x => x < pivot)
.quick_sort()
.concat(this.filter(x => x == pivot))
.concat(this.filter(x => x > pivot).quick_sort());
};

View file

@ -0,0 +1,33 @@
(function () {
'use strict';
// quickSort :: (Ord a) => [a] -> [a]
function quickSort(xs) {
if (xs.length) {
var h = xs[0],
[less, more] = partition(
x => x <= h,
xs.slice(1)
);
return [].concat.apply(
[], [quickSort(less), h, quickSort(more)]
);
} else return [];
}
// partition :: Predicate -> List -> (Matches, nonMatches)
// partition :: (a -> Bool) -> [a] -> ([a], [a])
function partition(p, xs) {
return xs.reduce((a, x) => (
a[p(x) ? 0 : 1].push(x),
a
), [[], []]);
}
return quickSort([11.8, 14.1, 21.3, 8.5, 16.7, 5.7]);
})();

View file

@ -0,0 +1,18 @@
fun quicksort(list: List<Int>): List<Int> {
if (list.size == 0) {
return listOf()
} else {
val head = list.first()
val tail = list.takeLast(list.size - 1)
val less = quicksort(tail.filter { it < head })
val high = quicksort(tail.filter { it >= head })
return less + head + high
}
}
fun main(args: Array<String>) {
val nums = listOf(9, 7, 9, 8, 1, 2, 3, 4, 1, 9, 8, 9, 2, 4, 2, 4, 6, 3)
println(quicksort(nums))
}

View file

@ -6,13 +6,10 @@ function quicksort(t, start, endi)
local pivot = start
for i = start + 1, endi do
if t[i] <= t[pivot] then
local temp = t[pivot + 1]
t[pivot + 1] = t[pivot]
if(i == pivot + 1) then
t[pivot] = temp
if i == pivot + 1 then
t[pivot],t[pivot+1] = t[pivot+1],t[pivot]
else
t[pivot] = t[i]
t[i] = temp
t[pivot],t[pivot+1],t[i] = t[i],t[pivot],t[pivot+1]
end
pivot = pivot + 1
end

View file

@ -0,0 +1,16 @@
function quicksort(t)
if #t<2 then return t end
local pivot=t[1]
local a,b,c={},{},{}
for _,v in ipairs(t) do
if v<pivot then a[#a+1]=v
elseif v>pivot then c[#c+1]=v
else b[#b+1]=v
end
end
a=quicksort(a)
c=quicksort(c)
for _,v in ipairs(b) do a[#a+1]=v end
for _,v in ipairs(c) do a[#a+1]=v end
return a
end

View file

@ -0,0 +1,18 @@
function quickSort(array $array) {
// base case
if (empty($array)) {
return $array;
}
$head = array_shift($array);
$tail = $array;
$lesser = array_filter($tail, function ($item) use ($head) {
return $item <= $head;
});
$bigger = array_filter($tail, function ($item) use ($head) {
return $item > $head;
});
return array_merge(quickSort($lesser), [$head], quickSort($bigger));
}
$testCase = [1, 4, 8, 2, 8, 0, 2, 8];
$result = quickSort($testCase);
echo sprintf("[%s] ==> [%s]\n", implode(', ', $testCase), implode(', ', $result));

View file

@ -1,41 +1,41 @@
/*REXX program sorts a stemmed array using the quicksort algorithm.*/
call gen@ /*generate the array elements. */
call show@ 'before sort' /*show before array elements.*/
call quickSort # /*invoke the quicksort routine.*/
call show@ ' after sort' /*show after array elements.*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────QUICKSORT subroutine────────────────*/
quickSort: procedure expose @. /*access the caller's local var. */
a.1=1; b.1=arg(1); $=1
do while $\==0; L=a.$; t=b.$; $=$-1; if t<2 then iterate
h=L+t-1
?=L+t%2
if @.h<@.L then if @.?<@.h then do; p=@.h; @.h=@.L; end
else if @.?>@.L then p=@.L
else do; p=@.?; @.?=@.L; end
else if @.?<@.l then p=@.L
else if @.?>@.h then do; p=@.h; @.h=@.L; end
else do; p=@.?; @.?=@.L; end
j=L+1
k=h
do forever
do j=j while j<=k & @.j<=p; end /*a tinie-tiny loop*/
do k=k by -1 while j <k & @.k>=p; end /*another " " */
if j>=k then leave /*segment finished?*/
_=@.j; @.j=@.k; @.k=_ /*swap j&k elements*/
end /*forever*/
k=j-1; @.L=@.k; @.k=p; $=$+1
if j<=? then do; a.$=j; b.$=h-j+1; $=$+1; a.$=L; b.$=k-L; end
eLse do; a.$=L; b.$=k-L; $=$+1; a.$=j; b.$=h-j+1; end
end /*whiLe $¬==0*/
return
/*──────────────────────────────────GEN@ subroutine─────────────────────*/
gen@: @.=; maxL=0 /*assign default value for array.*/
@.1 = " Rivers that form part of a (USA) state's border " /*this value is adjusted later to include a prefix & suffix.*/
@.2 = '=' /*this value is expanded later. */
/*REXX program sorts a stemmed array using the quicksort algorithm. */
call gen@ /*generate the elements for the array. */
call show@ 'before sort' /*show the before array elements. */
call qSort # /*invoke the quicksort subroutine. */
call show@ ' after sort' /*show the after array elements. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
qSort: procedure expose @.; a.1=1; b.1=arg(1) /*access the caller's local variable. */
$=1
do while $\==0; L=a.$; t=b.$; $=$-1; if t<2 then iterate
h=L+t-1; ?=L+t%2
if @.h<@.L then if @.?<@.h then do; p=@.h; @.h=@.L; end
else if @.?>@.L then p=@.L
else do; p=@.?; @.?=@.L; end
else if @.?<@.l then p=@.L
else if @.?>@.h then do; p=@.h; @.h=@.L; end
else do; p=@.?; @.?=@.L; end
j=L+1; k=h
do forever
do j=j while j<=k & @.j<=p; end /*a tinie-tiny loop.*/
do k=k by -1 while j <k & @.k>=p; end /*another " " */
if j>=k then leave /*segment finished? */
_=@.j; @.j=@.k; @.k=_ /*swap J&K elements.*/
end /*forever*/
$=$+1
k=j-1; @.L=@.k; @.k=p
if j<=? then do; a.$=j; b.$=h-j+1; $=$+1; a.$=L; b.$=k-L; end
eLse do; a.$=L; b.$=k-L; $=$+1; a.$=j; b.$=h-j+1; end
end /*whiLe $¬==0*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show@: w=length(#); do j=1 for #; say 'element' right(j,w) arg(1)":" @.j; end
say copies('', maxL + w + 22) /*display a separator (between outputs)*/
return
/*──────────────────────────────────GEN@ subroutine──────────────────────────────────────────────────────────────────────────────────────────────────────*/
gen@: @.=; maxL=0 /*assign default value for array.*/
@.1 = " Rivers that form part of a (USA) state's border " /*this value is adjusted later to include a prefix & suffix.*/
@.2 = '=' /*this value is expanded later. */
@.3 = "Perdido River Alabama, Florida"
@.4 = "Chattahoochee River Alabama, Georgia"
@.5 = "Tennessee River Alabama, Kentucky, Mississippi, Tennessee"
@ -98,17 +98,10 @@ gen@: @.=; maxL=0 /*assign default value for array.*/
@.62 = "Blackwater River North Carolina, Virginia"
@.63 = "Columbia River Oregon, Washington"
do #=1 while @.#\=='' /*find how many entries, and also*/
maxL=max(maxL, length(@.#)) /* find the maximum width entry.*/
end /*#*/
#=#-1 /*adjust the highest element #. */
@.1=centre(@.1, maxL, '-') /*adjust the header information. */
@.2=copies(@.2, maxL) /*adjust the header separator. */
return
/*──────────────────────────────────SHOW@ subroutine────────────────────*/
show@: widthH=length(#) /*maximum width of any line. */
do j=1 for # /*display each item in the array.*/
say 'element' right(j,widthH) arg(1)':' @.j
end /*j*/
say copies('', maxL + widthH + 22) /*display a separator line. */
do #=1 while @.#\=='' /*find how many entries in array, and */
maxL=max(maxL, length(@.#)) /* also find the maximum width entry.*/
end /*#*/
#=#-1 /*adjust the highest element number. */
@.1=center(@.1, maxL, '-') /* " " header information. */
@.2=copies(@.2, maxL) /* " " " separator. */
return

View file

@ -1,4 +1,4 @@
// Type alias for function that returns true if arguments are in the correct order
// Type alias for function that returns true if arguments should be swapped
type OrderFunc<T> = Fn(&T, &T) -> bool;
fn main() {
@ -6,25 +6,24 @@ fn main() {
let mut numbers = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1];
println!("Before: {:?}", numbers);
quick_sort(&mut numbers, &f);
quick_sort(&mut numbers, &is_less);
println!("After: {:?}", numbers);
// Sort strings
let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"];
println!("Before: {:?}", strings);
quick_sort(&mut strings, &f);
quick_sort(&mut strings, &is_less);
println!("After: {:?}", strings);
}
// Example OrderFunc which is used to order items from least to greatest
#[inline]
fn f<T: Ord>(x: &T, y: &T) -> bool {
#[inline(always)]
fn is_less<T: Ord>(x: &T, y: &T) -> bool {
x < y
}
// We use in place quick sort
// For details see http://en.wikipedia.org/wiki/Quicksort#In-place_version
fn quick_sort<T>(v: &mut [T], f: &OrderFunc<T>) {
let len = v.len();
@ -41,9 +40,6 @@ fn quick_sort<T>(v: &mut [T], f: &OrderFunc<T>) {
quick_sort(&mut v[pivot_index + 1..len], f);
}
// Reorders the slice with values lower than the pivot at the left side,
// and values bigger than it at the right side.
// Also returns the store index.
fn partition<T>(v: &mut [T], f: &OrderFunc<T>) -> usize {
let len = v.len();
let pivot_index = len / 2;

View file

@ -1,7 +1,11 @@
def quicksortInt(coll: List[Int]): List[Int] =
if (coll.isEmpty) {
coll
} else {
val (smaller, bigger) = coll.tail partition (_ < coll.head)
quicksortInt(smaller) ::: coll.head :: quicksortInt(bigger)
def sort(xs: List[Int]): List[Int] = {
xs match {
case Nil => Nil
case x :: xx => {
// Arbitrarily partition list in two
val (lo, hi) = xx.partition(_ < x)
// Sort each half
sort(lo) ++ (x :: sort(hi))
}
}
}

View file

@ -1,7 +1,9 @@
def quicksortFunc[T](coll: List[T], lessThan: (T, T) => Boolean): List[T] =
if (coll.isEmpty) {
coll
} else {
val (smaller, bigger) = coll.tail partition (lessThan(_, coll.head))
quicksortFunc(smaller, lessThan) ::: coll.head :: quicksortFunc(bigger, lessThan)
def sort[T](xs: List[T], lessThan: (T, T) => Boolean): List[T] = {
xs match {
case Nil => Nil
case x :: xx => {
val (lo, hi) = xx.partition(lessThan(_, x))
sort(lo, lessThan) ++ (x :: sort(hi, lessThan))
}
}
}

View file

@ -1,7 +1,9 @@
def quicksortOrd[T <% Ordered[T]](coll: List[T]): List[T] =
if (coll.isEmpty) {
coll
} else {
val (smaller, bigger) = coll.tail partition (_ < coll.head)
quicksortOrd(smaller) ::: coll.head :: quicksortOrd(bigger)
def sort[T](xs: List[T])(implicit ord: Ordering[T]): List[T] = {
xs match {
case Nil => Nil
case x :: xx => {
val (lo, hi) = xx.partition(ord.lt(_, x))
sort[T](lo) ++ (x :: sort[T](hi))
}
}
}

View file

@ -1,11 +1,9 @@
def quicksort
[T, CC[X] <: Seq[X] with SeqLike[X, CC[X]]] // My type parameters
(coll: CC[T]) // My explicit parameter
(implicit o: T => Ordered[T], cbf: CanBuildFrom[CC[T], T, CC[T]]) // My implicit parameters
: CC[T] = // My return type
if (coll.isEmpty) {
coll
} else {
val (smaller, bigger) = coll.tail partition (_ < coll.head)
quicksort(smaller) ++ (coll.head +: quicksort(bigger))
def sort[T <: Ordered[T]](xs: List[T]): List[T] = {
xs match {
case Nil => Nil
case x :: xx => {
val (lo, hi) = xx.partition(_ < x)
sort(lo) ++ (x :: sort(hi))
}
}
}

View file

@ -1,7 +1,17 @@
def quicksortInt(list: List[Int]): List[Int] = list match {
case List(head) => list
case head :: tail =>
val (smaller, bigger) = tail partition (_ < head)
quicksortInt(smaller) ::: head :: quicksortInt(bigger)
case _ => list
def sort[T, C[T] <: scala.collection.TraversableLike[T, C[T]]]
(xs: C[T])
(implicit ord: scala.math.Ordering[T],
cbf: scala.collection.generic.CanBuildFrom[C[T], T, C[T]]): C[T] = {
// Some collection types can't pattern match
if (xs.isEmpty) {
xs
} else {
val (lo, hi) = xs.tail.partition(ord.lt(_, xs.head))
val b = cbf()
b.sizeHint(xs.size)
b ++= sort(lo)
b += xs.head
b ++= sort(hi)
b.result()
}
}

View file

@ -5,3 +5,26 @@ fun quicksort [] = []
in
quicksort left @ [x] @ quicksort right
end
------------------------------------------------------------
Solution 2:
Without using List.partition
fun par_helper([], x, l, r) = (l, r) |
par_helper(h::t, x, l, r) =
if h <= x then
par_helper(t, x, l @ [h], r)
else
par_helper(t, x, l, r @ [h]);
fun par(l, x) = par_helper(l, x, [], []);
fun quicksort [] = []
| quicksort (h::t) =
let
val (left, right) = par(t, h)
in
quicksort left @ [h] @ quicksort right
end;