2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -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 '''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 <big> ''[[O]](n ''log'' n)'' </big> with the best pivots, to <big> ''[[O]](n<sup>2</sup>)'' </big> with the worst pivots, where <big> ''n'' </big> 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 [[../Merge sort|merge sort]], because both sorts have an average time of <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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
{5.7, 8.5, 11.8, 14.1, 16.7, 21.3}
|
||||
|
|
@ -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.
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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; });
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
[ 1, 3, 10, 11, 15, 19 ]
|
||||
|
|
@ -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])
|
||||
|
||||
})();
|
||||
|
|
@ -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());
|
||||
};
|
||||
|
|
@ -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]);
|
||||
|
||||
})();
|
||||
|
|
@ -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))
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue