I just had your ASObjC solution to the stats of the algorithms presented here. The cutoff for switching is somewhere between 10 and 100 items on my old hardware:
QuickSortImprovedStats-v2.pdf (51.6 KB).
I noted that ASObjC sorting on an almost sorted list (only 2 items swapped) is about the same as sorting a random created one.
Like pinpointed by many including Nigel, for sorting different type of lists, pure AppleScript has a use case. Here is the Improved Basic QuickSort modified with Nigel’s comparative script object. I use it a lot with lists of records:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
on QuickSort(ThisList, LeftEnd, RightEnd, CompObect)
-- Will sort items in place from LeftEnd trough RightEnd of TheList using a CompObject script
-- A basic recursive Quicksort, no logical optimisation
-- Based on S.A.R. (Tony) Hoare original algorithm, circa 1959
-- Dichotomic partionionning and code adapted from Niklaus Wirth Pascal version
-- A script object contains the list to allow much faster access to its items
script TonyHoare
property liste : ThisList
on QuickerSort(LeftEnd, RightEnd)
set pivot to my liste's item ((LeftEnd + RightEnd) div 2)
set i to LeftEnd
set j to RightEnd
repeat until i > j
set LeftValue to my liste's item i
repeat while CompObect's IsLarger(pivot, LeftValue)
set i to i + 1
set LeftValue to my liste's item i
end repeat
set RightValue to my liste's item j
repeat while CompObect's IsLarger(RightValue, pivot)
set j to j - 1
set RightValue to my liste's item j
end repeat
if j > i then --> swap items in the list
set my liste's item i to RightValue
set my liste's item j to LeftValue
else if i > j then
exit repeat
end if
set i to i + 1
set j to j - 1
end repeat
if j > LeftEnd then QuickerSort(LeftEnd, j)
if i < RightEnd then QuickerSort(i, RightEnd)
end QuickerSort
end script
TonyHoare's QuickerSort(LeftEnd, RightEnd)
end QuickSort
(* Exemples of CompObject script
script Ascending --> for a simple list, ascending order of sort
on IsLarger(x, y)
x > y
end IsLarger
end script
script Descending --> for a simple list, descending order of sort
on IsLarger(x, y)
x < y
end IsLarger
end script
*)
script ByAgeUp_FirstNameDown
on IsLarger(x, y)
set AgeOfX to x's Age
set AgeOfY to y's Age
(AgeOfX > AgeOfY) or ((AgeOfX = AgeOfY) and (x's FirtName < y's FirtName))
end IsLarger
end script
set MyList to {}
repeat 25 times
set the end of MyList to {FirtName:some character in "BCDFGHJKLMNPRSTVWXZ" & some character in "aeiouy" & ¬
some character in "bcdfgklmnprstxz", Age:random number from 1 to 100}
end repeat
QuickSort(MyList, 1, MyList's length, ByAgeUp_FirstNameDown)
--> {{FirtName:"Faf", Age:1}, {FirtName:"Zad", Age:2}, {FirtName:"Zuc", Age:3}, {FirtName:"Gap", Age:5}, {FirtName:"Bip", Age:5}, {FirtName:"Ryb", Age:15}, {FirtName:"Lyk", Age:15}, {FirtName:"Wud", Age:16}, {FirtName:"Rib", Age:21}, {FirtName:"Set", Age:22}, {FirtName:"Pop", Age:22}, {FirtName:"Gal", Age:23}, {FirtName:"Nud", Age:41}, {FirtName:"Xap", Age:46}, {FirtName:"Wig", Age:56}, {FirtName:"Cab", Age:56}, {FirtName:"Hud", Age:57}, {FirtName:"Vuk", Age:64}, {FirtName:"Pig", Age:64}, {FirtName:"Nod", Age:67}, {FirtName:"Sab", Age:80}, {FirtName:"Lum", Age:88}, {FirtName:"Vom", Age:89}, {FirtName:"Noz", Age:99}, {FirtName:"Det", Age:99}}