all tasks
This commit is contained in:
parent
b83f433714
commit
68f8f3e56b
14735 changed files with 178959 additions and 0 deletions
61
Task/Sorting-algorithms-Quicksort/0DESCRIPTION
Normal file
61
Task/Sorting-algorithms-Quicksort/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{{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.
|
||||
|
||||
# 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 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.
|
||||
|
||||
'''function''' ''quicksort''(array)
|
||||
less, equal, greater ''':=''' three empty arrays
|
||||
'''if''' length(array) > 1
|
||||
pivot ''':=''' ''select any element of'' array
|
||||
'''for each''' x '''in''' array
|
||||
'''if''' x < pivot '''then add''' x '''to''' less
|
||||
'''if''' x = pivot '''then add''' x '''to''' equal
|
||||
'''if''' x > pivot '''then add''' x '''to''' greater
|
||||
quicksort(less)
|
||||
quicksort(greater)
|
||||
array ''':=''' concatenate(less, equal, greater)
|
||||
|
||||
A better quicksort algorithm works in place, by swapping elements within the array, to avoid the memory allocation of more arrays.
|
||||
|
||||
'''function''' ''quicksort''(array)
|
||||
'''if''' length(array) > 1
|
||||
pivot ''':=''' ''select any element of'' array
|
||||
left ''':= first index of''' array
|
||||
right ''':=''' '''last index of''' array
|
||||
'''while''' left ≤ right
|
||||
'''while''' array[left] < pivot
|
||||
left := left + 1
|
||||
'''while''' array[right] > pivot
|
||||
right := right - 1
|
||||
'''if''' left ≤ right
|
||||
'''swap''' array[left] '''with''' array[right]
|
||||
left := left + 1
|
||||
right := right - 1
|
||||
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)''.
|
||||
|
||||
: ''"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
|
||||
|
||||
Quicksort is at one end of the spectrum of divide-and-conquer algorithms, with merge sort at the opposite end.
|
||||
|
||||
* 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.
|
||||
|
||||
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.
|
||||
2
Task/Sorting-algorithms-Quicksort/1META.yaml
Normal file
2
Task/Sorting-algorithms-Quicksort/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Sorting Algorithms
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
(defun partition (p xs)
|
||||
(if (endp xs)
|
||||
(mv nil nil)
|
||||
(mv-let (less more)
|
||||
(partition p (rest xs))
|
||||
(if (< (first xs) p)
|
||||
(mv (cons (first xs) less) more)
|
||||
(mv less (cons (first xs) more))))))
|
||||
|
||||
(defun qsort (xs)
|
||||
(if (endp xs)
|
||||
nil
|
||||
(mv-let (less more)
|
||||
(partition (first xs) (rest xs))
|
||||
(append (qsort less)
|
||||
(list (first xs))
|
||||
(qsort more)))))
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
> (qsort '(8 6 7 5 3 0 9))
|
||||
(0 3 5 6 7 8 9)
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
PROC partition =(REF [] DATA array, PROC (REF DATA, REF DATA) BOOL cmp)INT: (
|
||||
INT begin:=LWB array;
|
||||
INT end:=UPB array;
|
||||
WHILE begin < end DO
|
||||
WHILE begin < end DO
|
||||
IF cmp(array[begin], array[end]) THEN
|
||||
DATA tmp=array[begin];
|
||||
array[begin]:=array[end];
|
||||
array[end]:=tmp;
|
||||
GO TO break while decr end
|
||||
FI;
|
||||
end -:= 1
|
||||
OD;
|
||||
break while decr end: SKIP;
|
||||
WHILE begin < end DO
|
||||
IF cmp(array[begin], array[end]) THEN
|
||||
DATA tmp=array[begin];
|
||||
array[begin]:=array[end];
|
||||
array[end]:=tmp;
|
||||
GO TO break while incr begin
|
||||
FI;
|
||||
begin +:= 1
|
||||
OD;
|
||||
break while incr begin: SKIP
|
||||
OD;
|
||||
begin
|
||||
);
|
||||
|
||||
PROC qsort=(REF [] DATA array, PROC (REF DATA, REF DATA) BOOL cmp)VOID: (
|
||||
IF LWB array < UPB array THEN
|
||||
INT i := partition(array, cmp);
|
||||
PAR ( # remove PAR for single threaded sort #
|
||||
qsort(array[:i-1], cmp),
|
||||
qsort(array[i+1:], cmp)
|
||||
)
|
||||
FI
|
||||
);
|
||||
|
||||
MODE DATA = INT;
|
||||
PROC cmp=(REF DATA a,b)BOOL: a>b;
|
||||
|
||||
main:(
|
||||
[]DATA const l=(5,4,3,2,1);
|
||||
[UPB const l]DATA l:=const l;
|
||||
qsort(l,cmp);
|
||||
printf(($g(3)$,l))
|
||||
)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
qsort ← {1≥⍴⍵:⍵⋄e←⍵[?⍴⍵]⋄ (∇(⍵<e)/⍵) , ((⍵=e)/⍵) , ∇(⍵>e)/⍵}
|
||||
qsort 1 3 5 7 9 8 6 4 2
|
||||
1 2 3 4 5 6 7 8 9
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
# the following qsort implementation extracted from:
|
||||
#
|
||||
# ftp://ftp.armory.com/pub/lib/awk/qsort
|
||||
#
|
||||
# Copyleft GPLv2 John DuBois
|
||||
#
|
||||
# @(#) qsort 1.2.1 2005-10-21
|
||||
# 1990 john h. dubois iii (john@armory.com)
|
||||
#
|
||||
# qsortArbIndByValue(): Sort an array according to the values of its elements.
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# Arr[] is an array of values with arbitrary (associative) indices.
|
||||
#
|
||||
# Output variables:
|
||||
#
|
||||
# k[] is returned with numeric indices 1..n. The values assigned to these
|
||||
# indices are the indices of Arr[], ordered so that if Arr[] is stepped
|
||||
# through in the order Arr[k[1]] .. Arr[k[n]], it will be stepped through in
|
||||
# order of the values of its elements.
|
||||
#
|
||||
# Return value: The number of elements in the arrays (n).
|
||||
#
|
||||
# NOTES:
|
||||
#
|
||||
# Full example for accessing results:
|
||||
#
|
||||
# foolist["second"] = 2;
|
||||
# foolist["zero"] = 0;
|
||||
# foolist["third"] = 3;
|
||||
# foolist["first"] = 1;
|
||||
#
|
||||
# outlist[1] = 0;
|
||||
# n = qsortArbIndByValue(foolist, outlist)
|
||||
#
|
||||
# for (i = 1; i <= n; i++) {
|
||||
# printf("item at %s has value %d\n", outlist[i], foolist[outlist[i]]);
|
||||
# }
|
||||
# delete outlist;
|
||||
#
|
||||
function qsortArbIndByValue(Arr, k,
|
||||
ArrInd, ElNum)
|
||||
{
|
||||
ElNum = 0;
|
||||
for (ArrInd in Arr) {
|
||||
k[++ElNum] = ArrInd;
|
||||
}
|
||||
qsortSegment(Arr, k, 1, ElNum);
|
||||
return ElNum;
|
||||
}
|
||||
#
|
||||
# qsortSegment(): Sort a segment of an array.
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# Arr[] contains data with arbitrary indices.
|
||||
#
|
||||
# k[] has indices 1..nelem, with the indices of Arr[] as values.
|
||||
#
|
||||
# Output variables:
|
||||
#
|
||||
# k[] is modified by this function. The elements of Arr[] that are pointed to
|
||||
# by k[start..end] are sorted, with the values of elements of k[] swapped
|
||||
# so that when this function returns, Arr[k[start..end]] will be in order.
|
||||
#
|
||||
# Return value: None.
|
||||
#
|
||||
function qsortSegment(Arr, k, start, end,
|
||||
left, right, sepval, tmp, tmpe, tmps)
|
||||
{
|
||||
if ((end - start) < 1) { # 0 or 1 elements
|
||||
return;
|
||||
}
|
||||
# handle two-element case explicitly for a tiny speedup
|
||||
if ((end - start) == 1) {
|
||||
if (Arr[tmps = k[start]] > Arr[tmpe = k[end]]) {
|
||||
k[start] = tmpe;
|
||||
k[end] = tmps;
|
||||
}
|
||||
return;
|
||||
}
|
||||
# Make sure comparisons act on these as numbers
|
||||
left = start + 0;
|
||||
right = end + 0;
|
||||
sepval = Arr[k[int((left + right) / 2)]];
|
||||
# Make every element <= sepval be to the left of every element > sepval
|
||||
while (left < right) {
|
||||
while (Arr[k[left]] < sepval) {
|
||||
left++;
|
||||
}
|
||||
while (Arr[k[right]] > sepval) {
|
||||
right--;
|
||||
}
|
||||
if (left < right) {
|
||||
tmp = k[left];
|
||||
k[left++] = k[right];
|
||||
k[right--] = tmp;
|
||||
}
|
||||
}
|
||||
if (left == right)
|
||||
if (Arr[k[left]] < sepval) {
|
||||
left++;
|
||||
} else {
|
||||
right--;
|
||||
}
|
||||
if (start < right) {
|
||||
qsortSegment(Arr, k, start, right);
|
||||
}
|
||||
if (left < end) {
|
||||
qsortSegment(Arr, k, left, end);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
function quickSort (array:Array):Array
|
||||
{
|
||||
if (array.length <= 1)
|
||||
return array;
|
||||
|
||||
var pivot:Number = array[Math.round(array.length / 2)];
|
||||
|
||||
return quickSort(array.filter(function (x:Number, index:int, array:Array):Boolean { return x < pivot; })).concat(
|
||||
array.filter(function (x:Number, index:int, array:Array):Boolean { return x == pivot; })).concat(
|
||||
quickSort(array.filter(function (x:Number, index:int, array:Array):Boolean { return x > pivot; })));
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
function quickSort (array:Array):Array
|
||||
{
|
||||
if (array.length <= 1)
|
||||
return array;
|
||||
|
||||
var pivot:Number = array[Math.round(array.length / 2)];
|
||||
|
||||
var less:Array = [];
|
||||
var equal:Array = [];
|
||||
var greater:Array = [];
|
||||
|
||||
for each (var x:Number in array) {
|
||||
if (x < pivot)
|
||||
less.push(x);
|
||||
if (x == pivot)
|
||||
equal.push(x);
|
||||
if (x > pivot)
|
||||
greater.push(x);
|
||||
}
|
||||
|
||||
return quickSort(less).concat(
|
||||
equal).concat(
|
||||
quickSort(greater));
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
-----------------------------------------------------------------------
|
||||
-- Generic Quicksort procedure
|
||||
-----------------------------------------------------------------------
|
||||
generic
|
||||
type Element_Type is private;
|
||||
type Index_Type is (<>);
|
||||
type Element_Array is array(Index_Type range <>) of Element_Type;
|
||||
with function "<" (Left, Right : Element_Type) return Boolean is <>;
|
||||
with function ">" (Left, Right : Element_Type) return Boolean is <>;
|
||||
procedure Sort(Item : in out Element_Array);
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
-----------------------------------------------------------------------
|
||||
-- Generic Quicksort procedure
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
procedure Sort (Item : in out Element_Array) is
|
||||
|
||||
procedure Swap(Left, Right : in out Element_Type) is
|
||||
Temp : Element_Type := Left;
|
||||
begin
|
||||
Left := Right;
|
||||
Right := Temp;
|
||||
end Swap;
|
||||
|
||||
Pivot_Index : Index_Type;
|
||||
Pivot_Value : Element_Type;
|
||||
Right : Index_Type := Item'Last;
|
||||
Left : Index_Type := Item'First;
|
||||
|
||||
begin
|
||||
if Item'Length > 1 then
|
||||
Pivot_Index := Index_Type'Val((Index_Type'Pos(Item'Last) + 1 +
|
||||
Index_Type'Pos(Item'First)) / 2);
|
||||
Pivot_Value := Item(Pivot_Index);
|
||||
|
||||
Left := Item'First;
|
||||
Right := Item'Last;
|
||||
loop
|
||||
while Left < Item'Last and then Item(Left) < Pivot_Value loop
|
||||
Left := Index_Type'Succ(Left);
|
||||
end loop;
|
||||
while Right > Item'First and then Item(Right) > Pivot_Value loop
|
||||
Right := Index_Type'Pred(Right);
|
||||
end loop;
|
||||
exit when Left >= Right;
|
||||
Swap(Item(Left), Item(Right));
|
||||
if Left < Item'Last and Right > Item'First then
|
||||
Left := Index_Type'Succ(Left);
|
||||
Right := Index_Type'Pred(Right);
|
||||
end if;
|
||||
end loop;
|
||||
if Right > Item'First then
|
||||
Sort(Item(Item'First..Index_Type'Pred(Right)));
|
||||
end if;
|
||||
if Left < Item'Last then
|
||||
Sort(Item(Left..Item'Last));
|
||||
end if;
|
||||
end if;
|
||||
end Sort;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
with Sort;
|
||||
with Ada.Text_Io;
|
||||
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
|
||||
|
||||
procedure Sort_Test is
|
||||
type Days is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
|
||||
type Sales is array(Days range <>) of Float;
|
||||
procedure Sort_Days is new Sort(Float, Days, Sales);
|
||||
|
||||
procedure Print(Item : Sales) is
|
||||
begin
|
||||
for I in Item'range loop
|
||||
Put(Item => Item(I), Fore => 5, Aft => 2, Exp => 0);
|
||||
end loop;
|
||||
end Print;
|
||||
|
||||
Weekly_Sales : Sales := (Mon => 300.0,
|
||||
Tue => 700.0,
|
||||
Wed => 800.0,
|
||||
Thu => 500.0,
|
||||
Fri => 200.0,
|
||||
Sat => 100.0,
|
||||
Sun => 900.0);
|
||||
|
||||
begin
|
||||
|
||||
Print(Weekly_Sales);
|
||||
Ada.Text_Io.New_Line(2);
|
||||
Sort_Days(Weekly_Sales);
|
||||
Print(Weekly_Sales);
|
||||
|
||||
end Sort_Test;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
MsgBox % quicksort("8,4,9,2,1")
|
||||
|
||||
quicksort(list)
|
||||
{
|
||||
StringSplit, list, list, `,
|
||||
If (list0 <= 1)
|
||||
Return list
|
||||
pivot := list1
|
||||
Loop, Parse, list, `,
|
||||
{
|
||||
If (A_LoopField < pivot)
|
||||
less = %less%,%A_LoopField%
|
||||
Else If (A_LoopField > pivot)
|
||||
more = %more%,%A_LoopField%
|
||||
Else
|
||||
pivotlist = %pivotlist%,%A_LoopField%
|
||||
}
|
||||
StringTrimLeft, less, less, 1
|
||||
StringTrimLeft, more, more, 1
|
||||
StringTrimLeft, pivotList, pivotList, 1
|
||||
less := quicksort(less)
|
||||
more := quicksort(more)
|
||||
Return less . pivotList . more
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
DECLARE SUB quicksort (arr() AS INTEGER, leftN AS INTEGER, rightN AS INTEGER)
|
||||
|
||||
DIM q(99) AS INTEGER
|
||||
DIM n AS INTEGER
|
||||
|
||||
RANDOMIZE TIMER
|
||||
|
||||
FOR n = 0 TO 99
|
||||
q(n) = INT(RND * 9999)
|
||||
NEXT
|
||||
|
||||
OPEN "output.txt" FOR OUTPUT AS 1
|
||||
FOR n = 0 TO 99
|
||||
PRINT #1, q(n),
|
||||
NEXT
|
||||
PRINT #1,
|
||||
quicksort q(), 0, 99
|
||||
FOR n = 0 TO 99
|
||||
PRINT #1, q(n),
|
||||
NEXT
|
||||
CLOSE
|
||||
|
||||
SUB quicksort (arr() AS INTEGER, leftN AS INTEGER, rightN AS INTEGER)
|
||||
DIM pivot AS INTEGER, leftNIdx AS INTEGER, rightNIdx AS INTEGER
|
||||
leftNIdx = leftN
|
||||
rightNIdx = rightN
|
||||
IF (rightN - leftN) > 0 THEN
|
||||
pivot = (leftN + rightN) / 2
|
||||
WHILE (leftNIdx <= pivot) AND (rightNIdx >= pivot)
|
||||
WHILE (arr(leftNIdx) < arr(pivot)) AND (leftNIdx <= pivot)
|
||||
leftNIdx = leftNIdx + 1
|
||||
WEND
|
||||
WHILE (arr(rightNIdx) > arr(pivot)) AND (rightNIdx >= pivot)
|
||||
rightNIdx = rightNIdx - 1
|
||||
WEND
|
||||
SWAP arr(leftNIdx), arr(rightNIdx)
|
||||
leftNIdx = leftNIdx + 1
|
||||
rightNIdx = rightNIdx - 1
|
||||
IF (leftNIdx - 1) = pivot THEN
|
||||
rightNIdx = rightNIdx + 1
|
||||
pivot = rightNIdx
|
||||
ELSEIF (rightNIdx + 1) = pivot THEN
|
||||
leftNIdx = leftNIdx - 1
|
||||
pivot = leftNIdx
|
||||
END IF
|
||||
WEND
|
||||
quicksort arr(), leftN, pivot - 1
|
||||
quicksort arr(), pivot + 1, rightN
|
||||
END IF
|
||||
END SUB
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
DIM test(9)
|
||||
test() = 4, 65, 2, -31, 0, 99, 2, 83, 782, 1
|
||||
PROCquicksort(test(), 0, 10)
|
||||
FOR i% = 0 TO 9
|
||||
PRINT test(i%) ;
|
||||
NEXT
|
||||
PRINT
|
||||
END
|
||||
|
||||
DEF PROCquicksort(a(), s%, n%)
|
||||
LOCAL l%, p, r%, t%
|
||||
IF n% < 2 THEN ENDPROC
|
||||
t% = s% + n% - 1
|
||||
l% = s%
|
||||
r% = t%
|
||||
p = a((l% + r%) DIV 2)
|
||||
REPEAT
|
||||
WHILE a(l%) < p l% += 1 : ENDWHILE
|
||||
WHILE a(r%) > p r% -= 1 : ENDWHILE
|
||||
IF l% <= r% THEN
|
||||
SWAP a(l%), a(r%)
|
||||
l% += 1
|
||||
r% -= 1
|
||||
ENDIF
|
||||
UNTIL l% > r%
|
||||
IF s% < r% PROCquicksort(a(), s%, r% - s% + 1)
|
||||
IF l% < t% PROCquicksort(a(), l%, t% - l% + 1 )
|
||||
ENDPROC
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// This can be run using Cintcode BCPL freely available from www.cl.cam.ac.uk/users/mr10.
|
||||
|
||||
GET "libhdr.h"
|
||||
|
||||
LET quicksort(v, n) BE qsort(v+1, v+n)
|
||||
|
||||
AND qsort(l, r) BE
|
||||
{ WHILE l+8<r DO
|
||||
{ LET midpt = (l+r)/2
|
||||
// Select a good(ish) median value.
|
||||
LET val = middle(!l, !midpt, !r)
|
||||
LET i = partition(val, l, r)
|
||||
// Only use recursion on the smaller partition.
|
||||
TEST i>midpt THEN { qsort(i, r); r := i-1 }
|
||||
ELSE { qsort(l, i-1); l := i }
|
||||
}
|
||||
|
||||
FOR p = l+1 TO r DO // Now perform insertion sort.
|
||||
FOR q = p-1 TO l BY -1 TEST q!0<=q!1 THEN BREAK
|
||||
ELSE { LET t = q!0
|
||||
q!0 := q!1
|
||||
q!1 := t
|
||||
}
|
||||
}
|
||||
|
||||
AND middle(a, b, c) = a<b -> b<c -> b,
|
||||
a<c -> c,
|
||||
a,
|
||||
b<c -> a<c -> a,
|
||||
c,
|
||||
b
|
||||
|
||||
AND partition(median, p, q) = VALOF
|
||||
{ LET t = ?
|
||||
WHILE !p < median DO p := p+1
|
||||
WHILE !q > median DO q := q-1
|
||||
IF p>=q RESULTIS p
|
||||
t := !p
|
||||
!p := !q
|
||||
!q := t
|
||||
p, q := p+1, q-1
|
||||
} REPEAT
|
||||
|
||||
LET start() = VALOF {
|
||||
LET v = VEC 1000
|
||||
FOR i = 1 TO 1000 DO v!i := randno(1_000_000)
|
||||
quicksort(v, 1000)
|
||||
FOR i = 1 TO 1000 DO
|
||||
{ IF i MOD 10 = 0 DO newline()
|
||||
writef(" %i6", v!i)
|
||||
}
|
||||
newline()
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
#include <iterator>
|
||||
#include <algorithm> // for std::partition
|
||||
#include <functional> // for std::less
|
||||
|
||||
// helper function for median of three
|
||||
template<typename T>
|
||||
T median(T t1, T t2, T t3)
|
||||
{
|
||||
if (t1 < t2)
|
||||
{
|
||||
if (t2 < t3)
|
||||
return t2;
|
||||
else if (t1 < t3)
|
||||
return t3;
|
||||
else
|
||||
return t1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t1 < t3)
|
||||
return t1;
|
||||
else if (t2 < t3)
|
||||
return t3;
|
||||
else
|
||||
return t2;
|
||||
}
|
||||
}
|
||||
|
||||
// helper object to get <= from <
|
||||
template<typename Order> struct non_strict_op:
|
||||
public std::binary_function<typename Order::second_argument_type,
|
||||
typename Order::first_argument_type,
|
||||
bool>
|
||||
{
|
||||
non_strict_op(Order o): order(o) {}
|
||||
bool operator()(typename Order::second_argument_type arg1,
|
||||
typename Order::first_argument_type arg2) const
|
||||
{
|
||||
return !order(arg2, arg1);
|
||||
}
|
||||
private:
|
||||
Order order;
|
||||
};
|
||||
|
||||
template<typename Order> non_strict_op<Order> non_strict(Order o)
|
||||
{
|
||||
return non_strict_op<Order>(o);
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator,
|
||||
typename Order>
|
||||
void quicksort(RandomAccessIterator first, RandomAccessIterator last, Order order)
|
||||
{
|
||||
if (first != last && first+1 != last)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||
RandomAccessIterator mid = first + (last - first)/2;
|
||||
value_type pivot = median(*first, *mid, *(last-1));
|
||||
RandomAccessIterator split1 = std::partition(first, last, std::bind2nd(order, pivot));
|
||||
RandomAccessIterator split2 = std::partition(split1, last, std::bind2nd(non_strict(order), pivot));
|
||||
quicksort(first, split1, order);
|
||||
quicksort(split2, last, order);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
void quicksort(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
quicksort(first, last, std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>());
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#include <iterator>
|
||||
#include <algorithm> // for std::partition
|
||||
#include <functional> // for std::less
|
||||
|
||||
template<typename RandomAccessIterator,
|
||||
typename Order>
|
||||
void quicksort(RandomAccessIterator first, RandomAccessIterator last, Order order)
|
||||
{
|
||||
if (last - first > 1)
|
||||
{
|
||||
RandomAccessIterator split = std::partition(first+1, last, std::bind2nd(order, *first));
|
||||
std::iter_swap(first, split-1);
|
||||
quicksort(first, split-1, order);
|
||||
quicksort(split, last, order);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
void quicksort(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
quicksort(first, last, std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>());
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
void quick_sort (int *a, int n) {
|
||||
if (n < 2)
|
||||
return;
|
||||
int p = a[n / 2];
|
||||
int *l = a;
|
||||
int *r = a + n - 1;
|
||||
while (l <= r) {
|
||||
if (*l < p) {
|
||||
l++;
|
||||
continue;
|
||||
}
|
||||
if (*r > p) {
|
||||
r--;
|
||||
continue; // we need to check the condition (l <= r) every time we change the value of l or r
|
||||
}
|
||||
int t = *l;
|
||||
*l++ = *r;
|
||||
*r-- = t;
|
||||
}
|
||||
quick_sort(a, r - a + 1);
|
||||
quick_sort(l, a + n - l);
|
||||
}
|
||||
|
||||
int main () {
|
||||
int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};
|
||||
int n = sizeof a / sizeof a[0];
|
||||
quick_sort(a, n);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(defn qsort [L]
|
||||
(if (empty? L)
|
||||
'()
|
||||
(let [[pivot & L2] L]
|
||||
(lazy-cat (qsort (for [y L2 :when (< y pivot)] y))
|
||||
(list pivot)
|
||||
(qsort (for [y L2 :when (>= y pivot)] y))))))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(defn qsort [[pvt & rs]]
|
||||
(if pvt
|
||||
`(~@(qsort (filter #(< % pvt) rs))
|
||||
~pvt
|
||||
~@(qsort (filter #(>= % pvt) rs)))))
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(defn qsort [[pivot & xs]]
|
||||
(when pivot
|
||||
(let [smaller #(< % pivot)]
|
||||
(lazy-cat (qsort (filter smaller xs))
|
||||
[pivot]
|
||||
(qsort (remove smaller xs))))))
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(defn qsort3 [[pvt :as coll]]
|
||||
(when pvt
|
||||
(let [{left -1 mid 0 right 1} (group-by #(compare % pvt) coll)]
|
||||
(lazy-cat (qsort3 left) mid (qsort3 right)))))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(defn qsort3 [[pivot :as coll]]
|
||||
(when pivot
|
||||
(lazy-cat (qsort (filter #(< % pivot) coll))
|
||||
(filter #{pivot} coll)
|
||||
(qsort (filter #(> % pivot) coll)))))
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# This shows quicksort-in-place.
|
||||
quicksort = (a) ->
|
||||
swap = (i, j) ->
|
||||
return if i == j
|
||||
[a[i], a[j]] = [a[j], a[i]]
|
||||
|
||||
divide = (v, start, end) ->
|
||||
first_big = start
|
||||
j = start
|
||||
while j <= end
|
||||
if a[j] < v
|
||||
swap first_big, j
|
||||
first_big += 1
|
||||
j += 1
|
||||
first_big
|
||||
|
||||
partition = (start, end) ->
|
||||
v = a[end]
|
||||
first_big = divide v, start, end-1
|
||||
swap first_big, end
|
||||
first_big
|
||||
|
||||
qs = (start, end) ->
|
||||
return if start >= end
|
||||
m = partition start, end
|
||||
qs start, m-1
|
||||
qs m+1, end
|
||||
|
||||
qs 0, a.length - 1
|
||||
|
||||
# test
|
||||
do ->
|
||||
a = [1, 3, 5, 7, 9, 8, 6, 4, 2, 0, 3.5]
|
||||
quicksort(a)
|
||||
console.log a # [ 0, 1, 2, 3, 3.5, 4, 5, 6, 7, 8, 9 ]
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(defun quicksort (list &aux (pivot (car list)) )
|
||||
(if (cdr list)
|
||||
(nconc (quicksort (remove-if-not #'(lambda (x) (< x pivot)) list))
|
||||
(remove-if-not #'(lambda (x) (= x pivot)) list)
|
||||
(quicksort (remove-if-not #'(lambda (x) (> x pivot)) list)))
|
||||
list))
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(defun qs (list)
|
||||
(if (cdr list)
|
||||
(flet ((pivot (test)
|
||||
(remove (car list) list :test-not test)))
|
||||
(nconc (qs (pivot #'>)) (pivot #'=) (qs (pivot #'<))))
|
||||
list))
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
(defun quicksort (sequence)
|
||||
(labels ((swap (a b) (rotatef (elt sequence a) (elt sequence b)))
|
||||
(sub-sort (left right)
|
||||
(when (< left right)
|
||||
(let ((pivot (elt sequence right))
|
||||
(index left))
|
||||
(loop for i from left below right
|
||||
when (<= (elt sequence i) pivot)
|
||||
do (swap i (prog1 index (incf index))))
|
||||
(swap right index)
|
||||
(sub-sort left (1- index))
|
||||
(sub-sort (1+ index) right)))))
|
||||
(sub-sort 0 (1- (length sequence)))
|
||||
sequence))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
-- quicksort using higher-order functions:
|
||||
|
||||
qsort :: [Int] -> [Int]
|
||||
qsort [] = []
|
||||
qsort (x:l) = qsort (filter (<x) l) ++ x : qsort (filter (>=x) l)
|
||||
|
||||
goal = qsort [2,3,1,0]
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import std.stdio;
|
||||
|
||||
T[] quickSort(T)(T[] items) {
|
||||
if (items.length <= 1)
|
||||
return items;
|
||||
T[] less, more;
|
||||
foreach (x; items[1 .. $])
|
||||
(x < items[0] ? less : more) ~= x;
|
||||
return quickSort(less) ~ items[0] ~ quickSort(more);
|
||||
}
|
||||
|
||||
void main() {
|
||||
writeln(quickSort([4, 65, 2, -31, 0, 99, 2, 83, 782, 1]));
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import std.stdio;
|
||||
import std.algorithm;
|
||||
|
||||
void quickSort(T)(T[] items)
|
||||
{
|
||||
if (items.length >= 2) {
|
||||
auto parts = partition3(items, items[$ / 2]);
|
||||
quickSort(parts[0]);
|
||||
quickSort(parts[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
auto items = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1];
|
||||
quickSort(items);
|
||||
writeln(items);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
quickSort(List a) {
|
||||
if (a.length <= 1) {
|
||||
return a;
|
||||
}
|
||||
|
||||
var pivot = a[0];
|
||||
var less = [];
|
||||
var more = [];
|
||||
var pivotList = [];
|
||||
|
||||
// Partition
|
||||
a.forEach((var i){
|
||||
if (i.compareTo(pivot) < 0) {
|
||||
less.add(i);
|
||||
} else if (i.compareTo(pivot) > 0) {
|
||||
more.add(i);
|
||||
} else {
|
||||
pivotList.add(i);
|
||||
}
|
||||
});
|
||||
|
||||
// Recursively sort sublists
|
||||
less = quickSort(less);
|
||||
more = quickSort(more);
|
||||
|
||||
// Concatenate results
|
||||
less.addAll(pivotList);
|
||||
less.addAll(more);
|
||||
return less;
|
||||
}
|
||||
|
||||
void main() {
|
||||
var arr=[1,5,2,7,3,9,4,6,8];
|
||||
print("Before sort");
|
||||
arr.forEach((var i)=>print("$i"));
|
||||
arr = quickSort(arr);
|
||||
print("After sort");
|
||||
arr.forEach((var i)=>print("$i"));
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
def quicksort := {
|
||||
|
||||
def swap(container, ixA, ixB) {
|
||||
def temp := container[ixA]
|
||||
container[ixA] := container[ixB]
|
||||
container[ixB] := temp
|
||||
}
|
||||
|
||||
def partition(array, var first :int, var last :int) {
|
||||
if (last <= first) { return }
|
||||
|
||||
# Choose a pivot
|
||||
def pivot := array[def pivotIndex := (first + last) // 2]
|
||||
|
||||
# Move pivot to end temporarily
|
||||
swap(array, pivotIndex, last)
|
||||
|
||||
var swapWith := first
|
||||
|
||||
# Scan array except for pivot, and...
|
||||
for i in first..!last {
|
||||
if (array[i] <= pivot) { # items ≤ the pivot
|
||||
swap(array, i, swapWith) # are moved to consecutive positions on the left
|
||||
swapWith += 1
|
||||
}
|
||||
}
|
||||
|
||||
# Swap pivot into between-partition position.
|
||||
# Because of the swapping we know that everything before swapWith is less
|
||||
# than or equal to the pivot, and the item at swapWith (since it was not
|
||||
# swapped) is greater than the pivot, so inserting the pivot at swapWith
|
||||
# will preserve the partition.
|
||||
swap(array, swapWith, last)
|
||||
return swapWith
|
||||
}
|
||||
|
||||
def quicksortR(array, first :int, last :int) {
|
||||
if (last <= first) { return }
|
||||
def pivot := partition(array, first, last)
|
||||
quicksortR(array, first, pivot - 1)
|
||||
quicksortR(array, pivot + 1, last)
|
||||
}
|
||||
|
||||
def quicksort(array) { # returned from block
|
||||
quicksortR(array, 0, array.size() - 1)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
qsort([]) -> [];
|
||||
qsort([X|Xs]) ->
|
||||
qsort([ Y || Y <- Xs, Y < X]) ++ [X] ++ qsort([ Y || Y <- Xs, Y >= X]).
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
: qsort ( seq -- seq )
|
||||
dup empty? [
|
||||
unclip [ [ < ] curry partition [ qsort ] bi@ ] keep
|
||||
prefix append
|
||||
] unless ;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# (sort keep compare xs) sorts the list xs using the three-way comparison
|
||||
# function. It keeps duplicates if the keep flag is true, otherwise it
|
||||
# discards them and returns only the unique entries.
|
||||
|
||||
\sort ==
|
||||
(\keep\compare\xs
|
||||
xs end \x\xs
|
||||
|
||||
\lo = (filter (\y compare y x T F F) xs)
|
||||
\hi = (filter (\y compare y x F keep T) xs)
|
||||
|
||||
append (sort keep compare lo);
|
||||
item x;
|
||||
sort keep compare hi
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
defer lessthan ( a@ b@ -- ? ) ' < is lessthan
|
||||
|
||||
: mid ( l r -- mid ) over - 2/ -cell and + ;
|
||||
|
||||
: exch ( addr1 addr2 -- ) dup @ >r over @ swap ! r> swap ! ;
|
||||
|
||||
: partition ( l r -- l r r2 l2 )
|
||||
2dup mid @ >r ( r: pivot )
|
||||
2dup begin
|
||||
swap begin dup @ r@ lessthan while cell+ repeat
|
||||
swap begin r@ over @ lessthan while cell- repeat
|
||||
2dup <= if 2dup exch >r cell+ r> cell- then
|
||||
2dup > until r> drop ;
|
||||
|
||||
: qsort ( l r -- )
|
||||
partition swap rot
|
||||
\ 2over 2over - + < if 2swap then
|
||||
2dup < if recurse else 2drop then
|
||||
2dup < if recurse else 2drop then ;
|
||||
|
||||
: sort ( array len -- )
|
||||
dup 2 < if 2drop exit then
|
||||
1- cells over + qsort ;
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
MODULE Qsort_Module
|
||||
|
||||
IMPLICIT NONE
|
||||
|
||||
CONTAINS
|
||||
|
||||
RECURSIVE SUBROUTINE Qsort(a)
|
||||
|
||||
INTEGER, INTENT(IN OUT) :: a(:)
|
||||
INTEGER :: split
|
||||
|
||||
IF(size(a) > 1) THEN
|
||||
CALL Partition(a, split)
|
||||
CALL Qsort(a(:split-1))
|
||||
CALL Qsort(a(split:))
|
||||
END IF
|
||||
|
||||
END SUBROUTINE Qsort
|
||||
|
||||
SUBROUTINE Partition(a, marker)
|
||||
|
||||
INTEGER, INTENT(IN OUT) :: a(:)
|
||||
INTEGER, INTENT(OUT) :: marker
|
||||
INTEGER :: left, right, pivot, temp
|
||||
|
||||
pivot = (a(1) + a(size(a))) / 2 ! Average of first and last elements to prevent quadratic
|
||||
left = 0 ! behavior with sorted or reverse sorted data
|
||||
right = size(a) + 1
|
||||
|
||||
DO WHILE (left < right)
|
||||
right = right - 1
|
||||
DO WHILE (a(right) > pivot)
|
||||
right = right-1
|
||||
END DO
|
||||
left = left + 1
|
||||
DO WHILE (a(left) < pivot)
|
||||
left = left + 1
|
||||
END DO
|
||||
IF (left < right) THEN
|
||||
temp = a(left)
|
||||
a(left) = a(right)
|
||||
a(right) = temp
|
||||
END IF
|
||||
END DO
|
||||
|
||||
IF (left == right) THEN
|
||||
marker = left + 1
|
||||
ELSE
|
||||
marker = left
|
||||
END IF
|
||||
|
||||
END SUBROUTINE Partition
|
||||
|
||||
END MODULE Qsort_Module
|
||||
|
||||
PROGRAM Quicksort
|
||||
|
||||
USE Qsort_Module
|
||||
|
||||
IMPLICIT NONE
|
||||
INTEGER, PARAMETER :: n = 100
|
||||
INTEGER :: array(n)
|
||||
INTEGER :: i
|
||||
REAL :: x
|
||||
CALL RANDOM_SEED
|
||||
DO i = 1, n
|
||||
CALL RANDOM_NUMBER(x)
|
||||
array(i) = INT(x * 10000)
|
||||
END DO
|
||||
|
||||
WRITE (*, "(A)") "array is :-"
|
||||
WRITE (*, "(10I5)") array
|
||||
CALL Qsort(array)
|
||||
WRITE (*,*)
|
||||
WRITE (*, "(A)") "sorted array is :-"
|
||||
WRITE (*,"(10I5)") array
|
||||
|
||||
END PROGRAM Quicksort
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
list := []int{31, 41, 59, 26, 53, 58, 97, 93, 23, 84}
|
||||
fmt.Println("unsorted:", list)
|
||||
|
||||
quicksort(list)
|
||||
fmt.Println("sorted! ", list)
|
||||
}
|
||||
|
||||
func quicksort(a []int) {
|
||||
var pex func(int, int)
|
||||
pex = func(lower, upper int) {
|
||||
for {
|
||||
switch upper - lower {
|
||||
case -1, 0: // 0 or 1 item in segment. nothing to do here!
|
||||
return
|
||||
case 1: // 2 items in segment
|
||||
// < operator respects strict weak order
|
||||
if a[upper] < a[lower] {
|
||||
// a quick exchange and we're done.
|
||||
a[upper], a[lower] = a[lower], a[upper]
|
||||
}
|
||||
return
|
||||
// Hoare suggests optimized sort-3 or sort-4 algorithms here,
|
||||
// but does not provide an algorithm.
|
||||
}
|
||||
|
||||
// Hoare stresses picking a bound in a way to avoid worst case
|
||||
// behavior, but offers no suggestions other than picking a
|
||||
// random element. A function call to get a random number is
|
||||
// relatively expensive, so the method used here is to simply
|
||||
// choose the middle element. This at least avoids worst case
|
||||
// behavior for the obvious common case of an already sorted list.
|
||||
bx := (upper + lower) / 2
|
||||
b := a[bx] // b = Hoare's "bound" (aka "pivot")
|
||||
lp := lower // lp = Hoare's "lower pointer"
|
||||
up := upper // up = Hoare's "upper pointer"
|
||||
outer:
|
||||
for {
|
||||
// use < operator to respect strict weak order
|
||||
for lp < upper && !(b < a[lp]) {
|
||||
lp++
|
||||
}
|
||||
for {
|
||||
if lp > up {
|
||||
// "pointers crossed!"
|
||||
break outer
|
||||
}
|
||||
// < operator for strict weak order
|
||||
if a[up] < b {
|
||||
break // inner
|
||||
}
|
||||
up--
|
||||
}
|
||||
// exchange
|
||||
a[lp], a[up] = a[up], a[lp]
|
||||
lp++
|
||||
up--
|
||||
}
|
||||
// segment boundary is between up and lp, but lp-up might be
|
||||
// 1 or 2, so just call segment boundary between lp-1 and lp.
|
||||
if bx < lp {
|
||||
// bound was in lower segment
|
||||
if bx < lp-1 {
|
||||
// exchange bx with lp-1
|
||||
a[bx], a[lp-1] = a[lp-1], b
|
||||
}
|
||||
up = lp - 2
|
||||
} else {
|
||||
// bound was in upper segment
|
||||
if bx > lp {
|
||||
// exchange
|
||||
a[bx], a[lp] = a[lp], b
|
||||
}
|
||||
up = lp - 1
|
||||
lp++
|
||||
}
|
||||
// "postpone the larger of the two segments" = recurse on
|
||||
// the smaller segment, then iterate on the remaining one.
|
||||
if up-lower < upper-lp {
|
||||
pex(lower, up)
|
||||
lower = lp
|
||||
} else {
|
||||
pex(lp, upper)
|
||||
upper = up
|
||||
}
|
||||
}
|
||||
}
|
||||
pex(0, len(a)-1)
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
qsort [] = []
|
||||
qsort (x:xs) = qsort [y | y <- xs, y < x] ++ [x] ++ qsort [y | y <- xs, y >= x]
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import Data.List
|
||||
|
||||
qsort [] = []
|
||||
qsort (x:xs) = qsort ys ++ x : qsort zs where (ys, zs) = partition (< x) xs
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
function qs, arr
|
||||
if (count = n_elements(arr)) lt 2 then return,arr
|
||||
pivot = total(arr) / count ; use the average for want of a better choice
|
||||
return,[qs(arr[where(arr le pivot)]),qs(arr[where(arr gt pivot)])]
|
||||
end
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
procedure main() #: demonstrate various ways to sort a list and string
|
||||
demosort(quicksort,[3, 14, 1, 5, 9, 2, 6, 3],"qwerty")
|
||||
end
|
||||
|
||||
procedure quicksort(X,op,lower,upper) #: return sorted list
|
||||
local pivot,x
|
||||
|
||||
if /lower := 1 then { # top level call setup
|
||||
upper := *X
|
||||
op := sortop(op,X) # select how and what we sort
|
||||
}
|
||||
|
||||
if upper - lower > 0 then {
|
||||
every x := quickpartition(X,op,lower,upper) do # find a pivot and sort ...
|
||||
/pivot | X := x # ... how to return 2 values w/o a structure
|
||||
X := quicksort(X,op,lower,pivot-1) # ... left
|
||||
X := quicksort(X,op,pivot,upper) # ... right
|
||||
}
|
||||
|
||||
return X
|
||||
end
|
||||
|
||||
procedure quickpartition(X,op,lower,upper) #: quicksort partitioner helper
|
||||
local pivot
|
||||
static pivotL
|
||||
initial pivotL := list(3)
|
||||
|
||||
pivotL[1] := X[lower] # endpoints
|
||||
pivotL[2] := X[upper] # ... and
|
||||
pivotL[3] := X[lower+?(upper-lower)] # ... random midpoint
|
||||
if op(pivotL[2],pivotL[1]) then pivotL[2] :=: pivotL[1] # mini-
|
||||
if op(pivotL[3],pivotL[2]) then pivotL[3] :=: pivotL[2] # ... sort
|
||||
pivot := pivotL[2] # median is pivot
|
||||
|
||||
lower -:= 1
|
||||
upper +:= 1
|
||||
while lower < upper do { # find values on wrong side of pivot ...
|
||||
while op(pivot,X[upper -:= 1]) # ... rightmost
|
||||
while op(X[lower +:=1],pivot) # ... leftmost
|
||||
if lower < upper then # not crossed yet
|
||||
X[lower] :=: X[upper] # ... swap
|
||||
}
|
||||
|
||||
suspend lower # 1st return pivot point
|
||||
suspend X # 2nd return modified X (in case immutable)
|
||||
end
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
List do(
|
||||
quickSort := method(
|
||||
if(size > 1) then(
|
||||
pivot := at(size / 2 floor)
|
||||
return select(x, x < pivot) quickSort appendSeq(
|
||||
select(x, x == pivot) appendSeq(select(x, x > pivot) quickSort)
|
||||
)
|
||||
) else(return self)
|
||||
)
|
||||
|
||||
quickSortInPlace := method(
|
||||
copy(quickSort)
|
||||
)
|
||||
)
|
||||
|
||||
lst := list(5, -1, -4, 2, 9)
|
||||
lst quickSort println # ==> list(-4, -1, 2, 5, 9)
|
||||
lst quickSortInPlace println # ==> list(-4, -1, 2, 5, 9)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
sel=: 1 : 'x # ['
|
||||
|
||||
quicksort=: 3 : 0
|
||||
if.
|
||||
1 >: #y
|
||||
do.
|
||||
y
|
||||
else.
|
||||
e=. y{~?#y
|
||||
(quicksort y <sel e),(y =sel e),quicksort y >sel e
|
||||
end.
|
||||
)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
public static <E extends Comparable<? super E>> List<E> quickSort(List<E> arr) {
|
||||
if (arr.size() <= 1)
|
||||
return arr;
|
||||
E pivot = arr.getFirst(); //This pivot can change to get faster results
|
||||
|
||||
List<E> less = new LinkedList<E>();
|
||||
List<E> pivotList = new LinkedList<E>();
|
||||
List<E> more = new LinkedList<E>();
|
||||
|
||||
// Partition
|
||||
for (E i: arr) {
|
||||
if (i.compareTo(pivot) < 0)
|
||||
less.add(i);
|
||||
else if (i.compareTo(pivot) > 0)
|
||||
more.add(i);
|
||||
else
|
||||
pivotList.add(i);
|
||||
}
|
||||
|
||||
// Recursively sort sublists
|
||||
less = quickSort(less);
|
||||
more = quickSort(more);
|
||||
|
||||
// Concatenate results
|
||||
less.addAll(pivotList);
|
||||
less.addAll(more);
|
||||
return less;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
function sort(array, less) {
|
||||
|
||||
function swap(i, j) { var t=array[i]; array[i]=array[j]; array[j]=t }
|
||||
|
||||
function quicksort(left, right) {
|
||||
|
||||
if (left < right) {
|
||||
|
||||
var pivot = array[(left + right) >> 1];
|
||||
var left_new = left, right_new = right;
|
||||
|
||||
do {
|
||||
while (less(array[left_new], pivot)
|
||||
left_new++;
|
||||
while (less(pivot, array[right_new])
|
||||
right_new--;
|
||||
if (left_new <= right_new)
|
||||
swap(left_new++, right_new--);
|
||||
} while (left_new <= right_new);
|
||||
|
||||
quicksort(left, right_new);
|
||||
quicksort(left_new, right);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
quicksort(0, array.length-1);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Array.prototype.quick_sort = function ()
|
||||
{
|
||||
if (this.length <= 1)
|
||||
return this;
|
||||
|
||||
var pivot = this[Math.round(this.length / 2)];
|
||||
|
||||
return this.filter(function (x) { return x < pivot }).quick_sort().concat(
|
||||
this.filter(function (x) { return x == pivot })).concat(
|
||||
this.filter(function (x) { return x > pivot }).quick_sort());
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
DEFINE qsort ==
|
||||
[small] # termination condition: 0 or 1 element
|
||||
[] # do nothing
|
||||
[uncons [>] split] # pivot and two lists
|
||||
[enconcat] # insert the pivot after the recursion
|
||||
binrec. # recursion on the two lists
|
||||
|
|
@ -0,0 +1 @@
|
|||
quicksort:{f:*x@1?#x;:[0=#x;x;,/(_f x@&x<f;x@&x=f;_f x@&x>f)]}
|
||||
|
|
@ -0,0 +1 @@
|
|||
quicksort 1 3 5 7 9 8 6 4 2
|
||||
|
|
@ -0,0 +1 @@
|
|||
1 2 3 4 5 6 7 8 9
|
||||
|
|
@ -0,0 +1 @@
|
|||
_f()
|
||||
|
|
@ -0,0 +1 @@
|
|||
:[....]
|
||||
|
|
@ -0,0 +1 @@
|
|||
f:*x@1?#x
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
:[
|
||||
0=#x; / if length of x is zero
|
||||
x; / then return x
|
||||
/ else
|
||||
,/( / join the results of:
|
||||
_f x@&x<f / sort (recursively) elements less than f (pivot)
|
||||
x@&x=f / element equal to f
|
||||
_f x@&x>f) / sort (recursively) elements greater than f
|
||||
]
|
||||
|
|
@ -0,0 +1 @@
|
|||
t@<t:1 3 5 7 9 8 6 4 2
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
; quicksort (lists, functional)
|
||||
|
||||
to small? :list
|
||||
output or [empty? :list] [empty? butfirst :list]
|
||||
end
|
||||
to quicksort :list
|
||||
if small? :list [output :list]
|
||||
localmake "pivot first :list
|
||||
output (sentence
|
||||
quicksort filter [? < :pivot] butfirst :list
|
||||
filter [? = :pivot] :list
|
||||
quicksort filter [? > :pivot] butfirst :list
|
||||
)
|
||||
end
|
||||
|
||||
show quicksort [1 3 5 7 9 8 6 4 2]
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
; quicksort (arrays, in-place)
|
||||
|
||||
to incr :name
|
||||
make :name (thing :name) + 1
|
||||
end
|
||||
to decr :name
|
||||
make :name (thing :name) - 1
|
||||
end
|
||||
to swap :i :j :a
|
||||
localmake "t item :i :a
|
||||
setitem :i :a item :j :a
|
||||
setitem :j :a :t
|
||||
end
|
||||
|
||||
to quick :a :low :high
|
||||
if :high <= :low [stop]
|
||||
localmake "l :low
|
||||
localmake "h :high
|
||||
localmake "pivot item ashift (:l + :h) -1 :a
|
||||
do.while [
|
||||
while [(item :l :a) < :pivot] [incr "l]
|
||||
while [(item :h :a) > :pivot] [decr "h]
|
||||
if :l <= :h [swap :l :h :a incr "l decr "h]
|
||||
] [:l <= :h]
|
||||
quick :a :low :h
|
||||
quick :a :l :high
|
||||
end
|
||||
to sort :a
|
||||
quick :a first :a count :a
|
||||
end
|
||||
|
||||
make "test {1 3 5 7 9 8 6 4 2}
|
||||
sort :test
|
||||
show :test
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
quicksort(List, Sorted) :-
|
||||
quicksort(List, [], Sorted).
|
||||
|
||||
quicksort([], Sorted, Sorted).
|
||||
quicksort([Pivot| Rest], Acc, Sorted) :-
|
||||
partition(Rest, Pivot, Smaller0, Bigger0),
|
||||
quicksort(Smaller0, [Pivot| Bigger], Sorted),
|
||||
quicksort(Bigger0, Acc, Bigger).
|
||||
|
||||
partition([], _, [], []).
|
||||
partition([X| Xs], Pivot, Smalls, Bigs) :-
|
||||
( X @< Pivot ->
|
||||
Smalls = [X| Rest],
|
||||
partition(Xs, Pivot, Rest, Bigs)
|
||||
; Bigs = [X| Rest],
|
||||
partition(Xs, Pivot, Smalls, Rest)
|
||||
).
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
--in-place quicksort
|
||||
function quicksort(t, start, endi)
|
||||
start, endi = start or 1, endi or #t
|
||||
--partition w.r.t. first element
|
||||
if(endi - start < 2) then return t end
|
||||
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
|
||||
else
|
||||
t[pivot] = t[i]
|
||||
t[i] = temp
|
||||
end
|
||||
pivot = pivot + 1
|
||||
end
|
||||
end
|
||||
t = quicksort(t, start, pivot - 1)
|
||||
return quicksort(t, pivot + 1, endi)
|
||||
end
|
||||
|
||||
--example
|
||||
print(unpack(quicksort{5, 2, 7, 3, 4, 7, 1}))
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
qsort(a) = if eof(first a) then a else follow(qsort(b0),qsort(b1)) fi
|
||||
where
|
||||
p = first a < a;
|
||||
b0 = a whenever p;
|
||||
b1 = a whenever not p;
|
||||
follow(x,y) = if xdone then y upon xdone else x fi
|
||||
where
|
||||
xdone = iseod x fby xdone or iseod x;
|
||||
end;
|
||||
end
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
dnl return the first element of a list when called in the funny way seen below
|
||||
define(`arg1', `$1')dnl
|
||||
dnl
|
||||
dnl append lists 1 and 2
|
||||
define(`append',
|
||||
`ifelse(`$1',`()',
|
||||
`$2',
|
||||
`ifelse(`$2',`()',
|
||||
`$1',
|
||||
`substr($1,0,decr(len($1))),substr($2,1)')')')dnl
|
||||
dnl
|
||||
dnl separate list 2 based on pivot 1, appending to left 3 and right 4,
|
||||
dnl until 2 is empty, and then combine the sort of left with pivot with
|
||||
dnl sort of right
|
||||
define(`sep',
|
||||
`ifelse(`$2', `()',
|
||||
`append(append(quicksort($3),($1)),quicksort($4))',
|
||||
`ifelse(eval(arg1$2<=$1),1,
|
||||
`sep($1,(shift$2),append($3,(arg1$2)),$4)',
|
||||
`sep($1,(shift$2),$3,append($4,(arg1$2)))')')')dnl
|
||||
dnl
|
||||
dnl pick first element of list 1 as pivot and separate based on that
|
||||
define(`quicksort',
|
||||
`ifelse(`$1', `()',
|
||||
`()',
|
||||
`sep(arg1$1,(shift$1),`()',`()')')')dnl
|
||||
dnl
|
||||
quicksort((3,1,4,1,5,9))
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
function sortedArray = quickSort(array)
|
||||
|
||||
if numel(array) <= 1 %If the array has 1 element then it can't be sorted
|
||||
sortedArray = array;
|
||||
return
|
||||
end
|
||||
|
||||
pivot = array(end);
|
||||
array(end) = [];
|
||||
|
||||
%Create two new arrays which contain the elements that are less than or
|
||||
%equal to the pivot called "less" and greater than the pivot called
|
||||
%"greater"
|
||||
less = array( array <= pivot );
|
||||
greater = array( array > pivot );
|
||||
|
||||
%The sorted array is the concatenation of the sorted "less" array, the
|
||||
%pivot and the sorted "greater" array in that order
|
||||
sortedArray = [quickSort(less) pivot quickSort(greater)];
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
function sortedArray = quickSort(array)
|
||||
|
||||
if numel(array) <= 1 %If the array has 1 element then it can't be sorted
|
||||
sortedArray = array;
|
||||
return
|
||||
end
|
||||
|
||||
pivot = array(end);
|
||||
array(end) = [];
|
||||
|
||||
sortedArray = [quickSort( array(array <= pivot) ) pivot quickSort( array(array > pivot) )];
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
quickSort([4,3,7,-2,9,1])
|
||||
|
||||
ans =
|
||||
|
||||
-2 1 3 4 7 9
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
fn quickSort arr =
|
||||
(
|
||||
less = #()
|
||||
pivotList = #()
|
||||
more = #()
|
||||
if arr.count <= 1 then
|
||||
(
|
||||
arr
|
||||
)
|
||||
else
|
||||
(
|
||||
pivot = arr[arr.count/2]
|
||||
for i in arr do
|
||||
(
|
||||
case of
|
||||
(
|
||||
(i < pivot): (append less i)
|
||||
(i == pivot): (append pivotList i)
|
||||
(i > pivot): (append more i)
|
||||
)
|
||||
)
|
||||
less = quickSort less
|
||||
more = quickSort more
|
||||
less + pivotList + more
|
||||
)
|
||||
)
|
||||
a = #(4, 89, -3, 42, 5, 0, 2, 889)
|
||||
a = quickSort a
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
QuickSort[x_List] := Module[{pivot},
|
||||
If[Length@x <= 1, Return[x]];
|
||||
pivot = RandomChoice@x;
|
||||
Flatten@{QuickSort[Cases[x, j_ /; j < pivot]], Cases[x, j_ /; j == pivot], QuickSort[Cases[x, j_ /; j > pivot]]}
|
||||
]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(*#####################*)
|
||||
DEFINITION MODULE QSORT;
|
||||
(*#####################*)
|
||||
|
||||
FROM SYSTEM IMPORT ADDRESS;
|
||||
|
||||
TYPE CmpFuncPtrs = PROCEDURE(ADDRESS, ADDRESS):INTEGER;
|
||||
|
||||
PROCEDURE QuickSortPtrs(VAR Array:ARRAY OF ADDRESS; N:CARDINAL;
|
||||
Compare:CmpFuncPtrs);
|
||||
END QSORT.
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
(*##########################*)
|
||||
IMPLEMENTATION MODULE QSORT;
|
||||
(*##########################*)
|
||||
|
||||
FROM SYSTEM IMPORT ADDRESS;
|
||||
|
||||
CONST SmallPartition = 9;
|
||||
|
||||
(*
|
||||
NOTE
|
||||
1.Reference on QuickSort: "Implementing Quicksort Programs", Robert
|
||||
Sedgewick, Communications of the ACM, Oct 78, v21 #10.
|
||||
*)
|
||||
|
||||
(*==============================================================*)
|
||||
PROCEDURE QuickSortPtrs(VAR Array:ARRAY OF ADDRESS; N:CARDINAL;
|
||||
Compare:CmpFuncPtrs);
|
||||
(*==============================================================*)
|
||||
|
||||
(*-----------------------------*)
|
||||
PROCEDURE Swap(VAR A,B:ADDRESS);
|
||||
(*-----------------------------*)
|
||||
|
||||
VAR temp :ADDRESS;
|
||||
|
||||
BEGIN
|
||||
|
||||
temp := A; A := B; B := temp;
|
||||
|
||||
END Swap;
|
||||
|
||||
(*-------------------------------*)
|
||||
PROCEDURE TstSwap(VAR A,B:ADDRESS);
|
||||
(*-------------------------------*)
|
||||
|
||||
VAR temp :ADDRESS;
|
||||
|
||||
BEGIN
|
||||
|
||||
IF Compare(A,B) > 0 THEN
|
||||
temp := A; A := B; B := temp;
|
||||
END;
|
||||
|
||||
END TstSwap;
|
||||
|
||||
(*--------------*)
|
||||
PROCEDURE Isort;
|
||||
(*--------------*)
|
||||
(*
|
||||
Insertion sort.
|
||||
*)
|
||||
|
||||
VAR i,j :CARDINAL;
|
||||
temp :ADDRESS;
|
||||
|
||||
BEGIN
|
||||
|
||||
IF N < 2 THEN RETURN END;
|
||||
|
||||
FOR i := N-2 TO 0 BY -1 DO
|
||||
IF Compare(Array[i],Array[i+1]) > 0 THEN
|
||||
temp := Array[i];
|
||||
j := i+1;
|
||||
REPEAT
|
||||
Array[j-1] := Array[j];
|
||||
INC(j);
|
||||
UNTIL (j = N) OR (Compare(Array[j],temp) >= 0);
|
||||
Array[j-1] := temp;
|
||||
END;
|
||||
END;
|
||||
|
||||
END Isort;
|
||||
|
||||
(*----------------------------------*)
|
||||
PROCEDURE Quick(left,right:CARDINAL);
|
||||
(*----------------------------------*)
|
||||
|
||||
VAR
|
||||
i,j,
|
||||
second :CARDINAL;
|
||||
Partition :ADDRESS;
|
||||
|
||||
BEGIN
|
||||
|
||||
IF right > left THEN
|
||||
i := left; j := right;
|
||||
|
||||
Swap(Array[left],Array[(left+right) DIV 2]);
|
||||
|
||||
second := left+1; (* insure 2nd element is in *)
|
||||
TstSwap(Array[second], Array[right]); (* the lower part, last elem *)
|
||||
TstSwap(Array[left], Array[right]); (* in the upper part *)
|
||||
TstSwap(Array[second], Array[left]); (* THUS, only one test is *)
|
||||
(* needed in repeat loops *)
|
||||
Partition := Array[left];
|
||||
|
||||
LOOP
|
||||
REPEAT INC(i) UNTIL Compare(Array[i],Partition) >= 0;
|
||||
REPEAT DEC(j) UNTIL Compare(Array[j],Partition) <= 0;
|
||||
IF j < i THEN
|
||||
EXIT
|
||||
END;
|
||||
Swap(Array[i],Array[j]);
|
||||
END; (*loop*)
|
||||
Swap(Array[left],Array[j]);
|
||||
|
||||
IF (j > 0) AND (j-1-left >= SmallPartition) THEN
|
||||
Quick(left,j-1);
|
||||
END;
|
||||
IF right-i >= SmallPartition THEN
|
||||
Quick(i,right);
|
||||
END;
|
||||
END;
|
||||
|
||||
END Quick;
|
||||
|
||||
BEGIN (* QuickSortPtrs --------------------------------------------------*)
|
||||
|
||||
IF N > SmallPartition THEN (* won't work for 2 elements *)
|
||||
Quick(0,N-1);
|
||||
END;
|
||||
|
||||
Isort;
|
||||
|
||||
END QuickSortPtrs;
|
||||
|
||||
END QSORT.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
GENERIC INTERFACE ArraySort(Elem);
|
||||
|
||||
PROCEDURE Sort(VAR a: ARRAY OF Elem.T; cmp := Elem.Compare);
|
||||
|
||||
END ArraySort.
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
GENERIC MODULE ArraySort (Elem);
|
||||
|
||||
PROCEDURE Sort (VAR a: ARRAY OF Elem.T; cmp := Elem.Compare) =
|
||||
BEGIN
|
||||
QuickSort (a, 0, NUMBER (a), cmp);
|
||||
InsertionSort (a, 0, NUMBER (a), cmp);
|
||||
END Sort;
|
||||
|
||||
PROCEDURE QuickSort (VAR a: ARRAY OF Elem.T; lo, hi: INTEGER;
|
||||
cmp := Elem.Compare) =
|
||||
CONST CutOff = 9;
|
||||
VAR i, j: INTEGER; key, tmp: Elem.T;
|
||||
BEGIN
|
||||
WHILE (hi - lo > CutOff) DO (* sort a[lo..hi) *)
|
||||
|
||||
(* use median-of-3 to select a key *)
|
||||
i := (hi + lo) DIV 2;
|
||||
IF cmp (a[lo], a[i]) < 0 THEN
|
||||
IF cmp (a[i], a[hi-1]) < 0 THEN
|
||||
key := a[i];
|
||||
ELSIF cmp (a[lo], a[hi-1]) < 0 THEN
|
||||
key := a[hi-1]; a[hi-1] := a[i]; a[i] := key;
|
||||
ELSE
|
||||
key := a[lo]; a[lo] := a[hi-1]; a[hi-1] := a[i]; a[i] := key;
|
||||
END;
|
||||
ELSE (* a[lo] >= a[i] *)
|
||||
IF cmp (a[hi-1], a[i]) < 0 THEN
|
||||
key := a[i]; tmp := a[hi-1]; a[hi-1] := a[lo]; a[lo] := tmp;
|
||||
ELSIF cmp (a[lo], a[hi-1]) < 0 THEN
|
||||
key := a[lo]; a[lo] := a[i]; a[i] := key;
|
||||
ELSE
|
||||
key := a[hi-1]; a[hi-1] := a[lo]; a[lo] := a[i]; a[i] := key;
|
||||
END;
|
||||
END;
|
||||
|
||||
(* partition the array *)
|
||||
i := lo+1; j := hi-2;
|
||||
|
||||
(* find the first hole *)
|
||||
WHILE cmp (a[j], key) > 0 DO DEC (j) END;
|
||||
tmp := a[j];
|
||||
DEC (j);
|
||||
|
||||
LOOP
|
||||
IF (i > j) THEN EXIT END;
|
||||
|
||||
WHILE i < hi AND cmp (a[i], key) < 0 DO INC (i) END;
|
||||
IF (i > j) THEN EXIT END;
|
||||
a[j+1] := a[i];
|
||||
INC (i);
|
||||
|
||||
WHILE j > lo AND cmp (a[j], key) > 0 DO DEC (j) END;
|
||||
IF (i > j) THEN IF (j = i-1) THEN DEC (j) END; EXIT END;
|
||||
a[i-1] := a[j];
|
||||
DEC (j);
|
||||
END;
|
||||
|
||||
(* fill in the last hole *)
|
||||
a[j+1] := tmp;
|
||||
i := j+2;
|
||||
|
||||
(* then, recursively sort the smaller subfile *)
|
||||
IF (i - lo < hi - i)
|
||||
THEN QuickSort (a, lo, i-1, cmp); lo := i;
|
||||
ELSE QuickSort (a, i, hi, cmp); hi := i-1;
|
||||
END;
|
||||
|
||||
END; (* WHILE (hi-lo > CutOff) *)
|
||||
END QuickSort;
|
||||
|
||||
PROCEDURE InsertionSort (VAR a: ARRAY OF Elem.T; lo, hi: INTEGER;
|
||||
cmp := Elem.Compare) =
|
||||
VAR j: INTEGER; key: Elem.T;
|
||||
BEGIN
|
||||
FOR i := lo+1 TO hi-1 DO
|
||||
key := a[i];
|
||||
j := i-1;
|
||||
WHILE (j >= lo) AND cmp (key, a[j]) < 0 DO
|
||||
a[j+1] := a[j];
|
||||
DEC (j);
|
||||
END;
|
||||
a[j+1] := key;
|
||||
END;
|
||||
END InsertionSort;
|
||||
|
||||
BEGIN
|
||||
END ArraySort.
|
||||
|
|
@ -0,0 +1 @@
|
|||
INTERFACE TextSort = ArraySort(Text) END TextSort.
|
||||
|
|
@ -0,0 +1 @@
|
|||
MODULE TextSort = ArraySort(Text) END TextSort.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
MODULE Main;
|
||||
|
||||
IMPORT IO, TextSort;
|
||||
|
||||
VAR arr := ARRAY [1..10] OF TEXT {"Foo", "bar", "!ooF", "Modula-3", "hickup",
|
||||
"baz", "quuz", "Zeepf", "woo", "Rosetta Code"};
|
||||
|
||||
BEGIN
|
||||
TextSort.Sort(arr);
|
||||
FOR i := FIRST(arr) TO LAST(arr) DO
|
||||
IO.Put(arr[i] & "\n");
|
||||
END;
|
||||
END Main.
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Console;
|
||||
using Nemerle.Collections.NList;
|
||||
|
||||
module Quicksort
|
||||
{
|
||||
Qsort[T] (x : list[T]) : list[T]
|
||||
where T : IComparable
|
||||
{
|
||||
|[] => []
|
||||
|x::xs => Qsort($[y|y in xs, (y.CompareTo(x) < 0)]) + [x] + Qsort($[y|y in xs, (y.CompareTo(x) > 0)])
|
||||
}
|
||||
|
||||
Main() : void
|
||||
{
|
||||
def empty = [];
|
||||
def single = [2];
|
||||
def several = [2, 6, 1, 7, 3, 9, 4];
|
||||
WriteLine(Qsort(empty));
|
||||
WriteLine(Qsort(single));
|
||||
WriteLine(Qsort(several));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/* NetRexx */
|
||||
options replace format comments java crossref savelog symbols binary
|
||||
|
||||
import java.util.List
|
||||
|
||||
placesList = [String -
|
||||
"UK London", "US New York", "US Boston", "US Washington" -
|
||||
, "UK Washington", "US Birmingham", "UK Birmingham", "UK Boston" -
|
||||
]
|
||||
lists = [ -
|
||||
placesList -
|
||||
, quickSortSimple(String[] Arrays.copyOf(placesList, placesList.length)) -
|
||||
, quickSortInplace(String[] Arrays.copyOf(placesList, placesList.length)) -
|
||||
]
|
||||
|
||||
loop ln = 0 to lists.length - 1
|
||||
cl = lists[ln]
|
||||
loop ct = 0 to cl.length - 1
|
||||
say cl[ct]
|
||||
end ct
|
||||
say
|
||||
end ln
|
||||
|
||||
return
|
||||
|
||||
method quickSortSimple(array = String[]) public constant binary returns String[]
|
||||
|
||||
rl = String[array.length]
|
||||
al = List quickSortSimple(Arrays.asList(array))
|
||||
al.toArray(rl)
|
||||
|
||||
return rl
|
||||
|
||||
method quickSortSimple(array = List) public constant binary returns ArrayList
|
||||
|
||||
if array.size > 1 then do
|
||||
less = ArrayList()
|
||||
equal = ArrayList()
|
||||
greater = ArrayList()
|
||||
|
||||
pivot = array.get(Random().nextInt(array.size - 1))
|
||||
loop x_ = 0 to array.size - 1
|
||||
if (Comparable array.get(x_)).compareTo(Comparable pivot) < 0 then less.add(array.get(x_))
|
||||
if (Comparable array.get(x_)).compareTo(Comparable pivot) = 0 then equal.add(array.get(x_))
|
||||
if (Comparable array.get(x_)).compareTo(Comparable pivot) > 0 then greater.add(array.get(x_))
|
||||
end x_
|
||||
less = quickSortSimple(less)
|
||||
greater = quickSortSimple(greater)
|
||||
out = ArrayList(array.size)
|
||||
out.addAll(less)
|
||||
out.addAll(equal)
|
||||
out.addAll(greater)
|
||||
|
||||
array = out
|
||||
end
|
||||
|
||||
return ArrayList array
|
||||
|
||||
method quickSortInplace(array = String[]) public constant binary returns String[]
|
||||
|
||||
rl = String[array.length]
|
||||
al = List quickSortInplace(Arrays.asList(array))
|
||||
al.toArray(rl)
|
||||
|
||||
return rl
|
||||
|
||||
method quickSortInplace(array = List, ixL = int 0, ixR = int array.size - 1) public constant binary returns ArrayList
|
||||
|
||||
if ixL < ixR then do
|
||||
ixP = int ixL + (ixR - ixL) % 2
|
||||
ixP = quickSortInplacePartition(array, ixL, ixR, ixP)
|
||||
quickSortInplace(array, ixL, ixP - 1)
|
||||
quickSortInplace(array, ixP + 1, ixR)
|
||||
end
|
||||
|
||||
array = ArrayList(array)
|
||||
return ArrayList array
|
||||
|
||||
method quickSortInplacePartition(array = List, ixL = int, ixR = int, ixP = int) public constant binary returns int
|
||||
|
||||
pivotValue = array.get(ixP)
|
||||
rValue = array.get(ixR)
|
||||
array.set(ixP, rValue)
|
||||
array.set(ixR, pivotValue)
|
||||
ixStore = ixL
|
||||
loop i_ = ixL to ixR - 1
|
||||
iValue = array.get(i_)
|
||||
if (Comparable iValue).compareTo(Comparable pivotValue) < 0 then do
|
||||
storeValue = array.get(ixStore)
|
||||
array.set(i_, storeValue)
|
||||
array.set(ixStore, iValue)
|
||||
ixStore = ixStore + 1
|
||||
end
|
||||
end i_
|
||||
storeValue = array.get(ixStore)
|
||||
rValue = array.get(ixR)
|
||||
array.set(ixStore, rValue)
|
||||
array.set(ixR, storeValue)
|
||||
|
||||
return ixStore
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
quicksort is fork [ >= [1 first,tally],
|
||||
pass,
|
||||
link [
|
||||
quicksort sublist [ < [pass, first], pass ],
|
||||
sublist [ match [pass,first],pass ],
|
||||
quicksort sublist [ > [pass,first], pass ]
|
||||
]
|
||||
]
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
|quicksort [5, 8, 7, 4, 3]
|
||||
=3 4 5 7 8
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
proc QuickSort(list: seq[int]): seq[int] =
|
||||
if len(list) == 0:
|
||||
return @[]
|
||||
|
||||
var pivot = list[0]
|
||||
|
||||
var left: seq[int] = @[]
|
||||
var right: seq[int] = @[]
|
||||
for i in low(list)+1..high(list):
|
||||
if list[i] <= pivot:
|
||||
left.add(list[i])
|
||||
elif list[i] > pivot:
|
||||
right.add(list[i])
|
||||
|
||||
result = QuickSort(left)
|
||||
result.add(pivot)
|
||||
result.add(QuickSort(right))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
var sorted: seq[int] = QuickSort(@[5,2,1,6,2,3,1,2,123,21,54,6,1])
|
||||
for i in items(sorted):
|
||||
echo(i)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
let rec quicksort gt = function
|
||||
| [] -> []
|
||||
| x::xs ->
|
||||
let ys, zs = List.partition (gt x) xs in
|
||||
(quicksort gt ys) @ (x :: (quicksort gt zs))
|
||||
|
||||
let _ =
|
||||
quicksort (>) [4; 65; 2; -31; 0; 99; 83; 782; 1]
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
class QuickSort {
|
||||
function : Main(args : String[]) ~ Nil {
|
||||
array := [1, 3, 5, 7, 9, 8, 6, 4, 2];
|
||||
Sort(array);
|
||||
each(i : array) {
|
||||
array[i]->PrintLine();
|
||||
};
|
||||
}
|
||||
|
||||
function : Sort(array : Int[]) ~ Nil {
|
||||
size := array->Size();
|
||||
if(size <= 1) {
|
||||
return;
|
||||
};
|
||||
Sort(array, 0, size - 1);
|
||||
}
|
||||
|
||||
function : native : Sort(array : Int[], low : Int, high : Int) ~ Nil {
|
||||
i := low; j := high;
|
||||
pivot := array[low + (high-low)/2];
|
||||
|
||||
while(i <= j) {
|
||||
while(array[i] < pivot) {
|
||||
i+=1;
|
||||
};
|
||||
|
||||
while(array[j] > pivot) {
|
||||
j-=1;
|
||||
};
|
||||
|
||||
if (i <= j) {
|
||||
temp := array[i];
|
||||
array[i] := array[j];
|
||||
array[j] := temp;
|
||||
i+=1; j-=1;
|
||||
};
|
||||
};
|
||||
|
||||
if(low < j) {
|
||||
Sort(array, low, j);
|
||||
};
|
||||
|
||||
if(i < high) {
|
||||
Sort(array, i, high);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
function f=quicksort(v) % v must be a column vector
|
||||
f = v; n=length(v);
|
||||
if(n > 1)
|
||||
vl = min(f); vh = max(f); % min, max
|
||||
p = (vl+vh)*0.5; % pivot
|
||||
ia = find(f < p); ib = find(f == p); ic=find(f > p);
|
||||
f = [quicksort(f(ia)); f(ib); quicksort(f(ic))];
|
||||
end
|
||||
endfunction
|
||||
|
||||
N=30; v=rand(N,1); tic,u=quicksort(v); toc
|
||||
u
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
declare
|
||||
fun {QuickSort Xs}
|
||||
case Xs of nil then nil
|
||||
[] Pivot|Xr then
|
||||
fun {IsSmaller X} X < Pivot end
|
||||
Smaller Larger
|
||||
in
|
||||
{List.partition Xr IsSmaller ?Smaller ?Larger}
|
||||
{Append {QuickSort Smaller} Pivot|{QuickSort Larger}}
|
||||
end
|
||||
end
|
||||
in
|
||||
{Show {QuickSort [3 1 4 1 5 9 2 6 5]}}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
quickSort(v)={
|
||||
if(#v<2, return(v));
|
||||
my(less=List(),more=List(),same=List(),pivot);
|
||||
pivot=median([v[random(#v)+1],v[random(#v)+1],v[random(#v)+1]]); \\ Middle-of-three
|
||||
for(i=1,#v,
|
||||
if(v[i]<pivot,
|
||||
listput(less, v[i]),
|
||||
if(v[i]==pivot, listput(same, v[i]), listput(more, v[i]))
|
||||
)
|
||||
);
|
||||
concat(quickSort(Vec(less)), concat(Vec(same), quickSort(Vec(more))))
|
||||
};
|
||||
median(v)={
|
||||
vecsort(v)[#v>>1]
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
function quicksort($arr){
|
||||
$loe = $gt = array();
|
||||
if(count($arr) < 2){
|
||||
return $arr;
|
||||
}
|
||||
$pivot_key = key($arr);
|
||||
$pivot = array_shift($arr);
|
||||
foreach($arr as $val){
|
||||
if($val <= $pivot){
|
||||
$loe[] = $val;
|
||||
}elseif ($val > $pivot){
|
||||
$gt[] = $val;
|
||||
}
|
||||
}
|
||||
return array_merge(quicksort($loe),array($pivot_key=>$pivot),quicksort($gt));
|
||||
}
|
||||
|
||||
$arr = array(1, 3, 5, 7, 9, 8, 6, 4, 2);
|
||||
$arr = quicksort($arr);
|
||||
echo implode(',',$arr);
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
DCL (T(20)) FIXED BIN(31); /* scratch space of length N */
|
||||
|
||||
QUICKSORT: PROCEDURE (A,AMIN,AMAX,N) RECURSIVE ;
|
||||
DECLARE (A(*)) FIXED BIN(31);
|
||||
DECLARE (N,AMIN,AMAX) FIXED BIN(31) NONASGN;
|
||||
DECLARE (I,J,IA,IB,IC,PIV) FIXED BIN(31);
|
||||
DECLARE (P,Q) POINTER;
|
||||
DECLARE (AP(1)) FIXED BIN(31) BASED(P);
|
||||
|
||||
IF(N <= 1)THEN RETURN;
|
||||
IA=0; IB=0; IC=N+1;
|
||||
PIV=(AMIN+AMAX)/2;
|
||||
DO I=1 TO N;
|
||||
IF(A(I) < PIV)THEN DO;
|
||||
IA+=1; A(IA)=A(I);
|
||||
END; ELSE IF(A(I) > PIV) THEN DO;
|
||||
IC-=1; T(IC)=A(I);
|
||||
END; ELSE DO;
|
||||
IB+=1; T(IB)=A(I);
|
||||
END;
|
||||
END;
|
||||
DO I=1 TO IB; A(I+IA)=T(I); END;
|
||||
DO I=IC TO N; A(I)=T(N+IC-I); END;
|
||||
P=ADDR(A(IC));
|
||||
IC=N+1-IC;
|
||||
IF(IA > 1) THEN CALL QUICKSORT(A, AMIN, PIV-1,IA);
|
||||
IF(IC > 1) THEN CALL QUICKSORT(AP,PIV+1,AMAX, IC);
|
||||
RETURN;
|
||||
END QUICKSORT;
|
||||
MINMAX: PROC(A,AMIN,AMAX,N);
|
||||
DCL (AMIN,AMAX) FIXED BIN(31),
|
||||
(N,A(*)) FIXED BIN(31) NONASGN ;
|
||||
DCL (I,X,Y) FIXED BIN(31);
|
||||
|
||||
AMIN=A(N); AMAX=AMIN;
|
||||
DO I=1 TO N-1;
|
||||
X=A(I); Y=A(I+1);
|
||||
IF (X < Y)THEN DO;
|
||||
IF (X < AMIN) THEN AMIN=X;
|
||||
IF (Y > AMAX) THEN AMAX=Y;
|
||||
END; ELSE DO;
|
||||
IF (X > AMAX) THEN AMAX=X;
|
||||
IF (Y < AMIN) THEN AMIN=Y;
|
||||
END;
|
||||
END;
|
||||
RETURN;
|
||||
END MINMAX;
|
||||
CALL MINMAX(A,AMIN,AMAX,N);
|
||||
CALL QUICKSORT(A,AMIN,AMAX,N);
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{ X is array of LongInt }
|
||||
Procedure QuickSort ( Left, Right : LongInt );
|
||||
Var
|
||||
i, j : LongInt;
|
||||
tmp, pivot : LongInt; { tmp & pivot are the same type as the elements of array }
|
||||
Begin
|
||||
i:=Left;
|
||||
j:=Right;
|
||||
pivot := X[(Left + Right) shr 1]; // pivot := X[(Left + Rigth) div 2]
|
||||
Repeat
|
||||
While pivot > X[i] Do i:=i+1;
|
||||
While pivot < X[j] Do j:=j-1;
|
||||
If i<j Then Begin
|
||||
tmp:=X[i];
|
||||
X[i]:=X[j];
|
||||
X[j]:=tmp;
|
||||
j:=j-1;
|
||||
i:=i+1;
|
||||
End;
|
||||
Until i>j;
|
||||
If Left<j Then QuickSort(Left,j);
|
||||
If i<Right Then QuickSort(i,Right);
|
||||
End;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Empty list sorts to the empty list
|
||||
multi quicksort([]) { () }
|
||||
|
||||
# Otherwise, extract first item as pivot...
|
||||
multi quicksort([$pivot, *@rest]) {
|
||||
# Partition.
|
||||
my @before := @rest.grep(* before $pivot);
|
||||
my @after := @rest.grep(* !before $pivot);
|
||||
|
||||
# Sort the partitions.
|
||||
(quicksort(@before), $pivot, quicksort(@after))
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
sub quick_sort {
|
||||
my @a = @_;
|
||||
return @a if @a < 2;
|
||||
my $p = pop @a;
|
||||
quick_sort(grep $_ < $p, @a), $p, quick_sort(grep $_ >= $p, @a);
|
||||
}
|
||||
|
||||
my @a = (4, 65, 2, -31, 0, 99, 83, 782, 1);
|
||||
@a = quick_sort @a;
|
||||
print "@a\n";
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(de quicksort (L)
|
||||
(if (cdr L)
|
||||
(let Pivot (car L)
|
||||
(append (quicksort (filter '((A) (< A Pivot)) (cdr L)))
|
||||
(filter '((A) (= A Pivot)) L )
|
||||
(quicksort (filter '((A) (> A Pivot)) (cdr L)))) )
|
||||
L) )
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
Function SortThree( [Array] $data )
|
||||
{
|
||||
if( $data[ 0 ] -gt $data[ 1 ] )
|
||||
{
|
||||
if( $data[ 0 ] -lt $data[ 2 ] )
|
||||
{
|
||||
$data = $data[ 1, 0, 2 ]
|
||||
} elseif ( $data[ 1 ] -lt $data[ 2 ] ){
|
||||
$data = $data[ 1, 2, 0 ]
|
||||
} else {
|
||||
$data = $data[ 2, 1, 0 ]
|
||||
}
|
||||
} else {
|
||||
if( $data[ 0 ] -gt $data[ 2 ] )
|
||||
{
|
||||
$data = $data[ 2, 0, 1 ]
|
||||
} elseif( $data[ 1 ] -gt $data[ 2 ] ) {
|
||||
$data = $data[ 0, 2, 1 ]
|
||||
}
|
||||
}
|
||||
$data
|
||||
}
|
||||
|
||||
Function QuickSort( [Array] $data, $rand = ( New-Object Random ) )
|
||||
{
|
||||
$datal = $data.length
|
||||
if( $datal -gt 3 )
|
||||
{
|
||||
[void] $datal--
|
||||
$median = ( SortThree $data[ 0, ( $rand.Next( 1, $datal - 1 ) ), -1 ] )[ 1 ]
|
||||
$lt = @()
|
||||
$eq = @()
|
||||
$gt = @()
|
||||
$data | ForEach-Object { if( $_ -lt $median ) { $lt += $_ } elseif( $_ -eq $median ) { $eq += $_ } else { $gt += $_ } }
|
||||
$lt = ( QuickSort $lt $rand )
|
||||
$gt = ( QuickSort $gt $rand )
|
||||
$data = @($lt) + $eq + $gt
|
||||
} elseif( $datal -eq 3 ) {
|
||||
$data = SortThree( $data )
|
||||
} elseif( $datal -eq 2 ) {
|
||||
if( $data[ 0 ] -gt $data[ 1 ] )
|
||||
{
|
||||
$data = $data[ 1, 0 ]
|
||||
}
|
||||
}
|
||||
$data
|
||||
}
|
||||
|
||||
QuickSort 5,3,1,2,4
|
||||
QuickSort 'e','c','a','b','d'
|
||||
QuickSort 0.5,0.3,0.1,0.2,0.4
|
||||
$l = 100; QuickSort ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( 0, $l - 1 ) } )
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
qsort( [], [] ).
|
||||
qsort( [H|U], S ) :- splitBy(H, U, L, R), qsort(L, SL), qsort(R, SR), append(SL, [H|SR], S).
|
||||
|
||||
% splitBy( H, U, LS, RS )
|
||||
% True if LS = { L in U | L <= H }; RS = { R in U | R > H }
|
||||
splitBy( _, [], [], []).
|
||||
splitBy( H, [U|T], [U|LS], RS ) :- U =< H, splitBy(H, T, LS, RS).
|
||||
splitBy( H, [U|T], LS, [U|RS] ) :- U > H, splitBy(H, T, LS, RS).
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
Procedure qSort(Array a(1), firstIndex, lastIndex)
|
||||
Protected low, high, pivotValue
|
||||
|
||||
low = firstIndex
|
||||
high = lastIndex
|
||||
pivotValue = a((firstIndex + lastIndex) / 2)
|
||||
|
||||
Repeat
|
||||
|
||||
While a(low) < pivotValue
|
||||
low + 1
|
||||
Wend
|
||||
|
||||
While a(high) > pivotValue
|
||||
high - 1
|
||||
Wend
|
||||
|
||||
If low <= high
|
||||
Swap a(low), a(high)
|
||||
low + 1
|
||||
high - 1
|
||||
EndIf
|
||||
|
||||
Until low > high
|
||||
|
||||
If firstIndex < high
|
||||
qSort(a(), firstIndex, high)
|
||||
EndIf
|
||||
|
||||
If low < lastIndex
|
||||
qSort(a(), low, lastIndex)
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
Procedure quickSort(Array a(1))
|
||||
qSort(a(),0,ArraySize(a()))
|
||||
EndProcedure
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
def quickSort(arr):
|
||||
less = []
|
||||
pivotList = []
|
||||
more = []
|
||||
if len(arr) <= 1:
|
||||
return arr
|
||||
else:
|
||||
pivot = arr[0]
|
||||
for i in arr:
|
||||
if i < pivot:
|
||||
less.append(i)
|
||||
elif i > pivot:
|
||||
more.append(i)
|
||||
else:
|
||||
pivotList.append(i)
|
||||
less = quickSort(less)
|
||||
more = quickSort(more)
|
||||
return less + pivotList + more
|
||||
|
||||
a = [4, 65, 2, -31, 0, 99, 83, 782, 1]
|
||||
a = quickSort(a)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
def qsort(L):
|
||||
return (qsort([y for y in L[1:] if y < L[0]]) +
|
||||
L[:1] +
|
||||
qsort([y for y in L[1:] if y >= L[0]])) if len(L) > 1 else L
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
def qsort(list):
|
||||
if not list:
|
||||
return []
|
||||
else:
|
||||
pivot = list[0]
|
||||
less = [x for x in list if x < pivot]
|
||||
more = [x for x in list[1:] if x >= pivot]
|
||||
return qsort(less) + [pivot] + qsort(more)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
(define keep
|
||||
_ [] -> []
|
||||
Pred [A|Rest] -> [A | (keep Pred Rest)] where (Pred A)
|
||||
Pred [_|Rest] -> (keep Pred Rest))
|
||||
|
||||
(define quicksort
|
||||
[] -> []
|
||||
[A|R] -> (append (quicksort (keep (>= A) R))
|
||||
[A]
|
||||
(quicksort (keep (< A) R))))
|
||||
|
||||
(quicksort [6 8 5 9 3 2 2 1 4 7])
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
qsort <- function(v) {
|
||||
if ( length(v) > 1 )
|
||||
{
|
||||
pivot <- (min(v) + max(v))/2.0 # Could also use pivot <- median(v)
|
||||
c(qsort(v[v < pivot]), v[v == pivot], qsort(v[v > pivot]))
|
||||
} else v
|
||||
}
|
||||
|
||||
N <- 100
|
||||
vs <- runif(N)
|
||||
system.time(u <- qsort(vs))
|
||||
print(u)
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue