There’s not much that can be done to make a bubble sort fast, but it can be an interesting exercise to try and make it as “least slow” as possible.
The algorithm I learned years ago involved cycling repeatedly through the list, comparing adjacent items and swapping them when necessary. The sort was complete when a clear run took place with no swaps. But StefanK posted a version in the OS X forum the other day (I don’t know if it was his own or somebody else’s) which makes use of the fact that the “highest” value in the list is bound to end up in the last slot during the first cycle. This item doesn’t need to be included in the next cycle and in fact each subsequent cycle can be one item shorter than the one preceding it. This reduces the total number of comparisons done over the course of the sort and the process is complete when there are less than two items left to consider.
on bubblesort(array)
repeat with i from length of array to 2 by -1 --> go backwards
repeat with j from 1 to i - 1 --> go forwards
tell array
if item j > item (j + 1) then
set {item j, item (j + 1)} to {item (j + 1), item j} -- swap
end if
end tell
end repeat
end repeat
return array
end bubblesort
However, on my old 400 MHz PowerBook, this takes 268.43 seconds to sort only 500 random integers! But the time can be reduced to 5.64 seconds with the coding below. Besides using the old referencing-via-script-object trick, it dispenses with the setting of multiple items by list “ which is time consuming “ and assigns the current values to variables so that they’re only read from the list once. At the end of each iteration of the inner repeat, the higher value of the current pair is preserved in the variable ‘a’ so that it doesn’t need to be read again from the list on the next iteration.
on bubblesort(theList)
script o
property lst : theList
end script
repeat with i from (count theList) to 2 by -1
set a to beginning of o's lst
repeat with j from 2 to i
set b to item j of o's lst
if (a > b) then
set item (j - 1) of o's lst to b
set item j of o's lst to a
else
set a to b
end if
end repeat
end repeat
end bubblesort
13th September 2010: I’ve uploaded a new version of this script with more flexible range parameters, as part of a collection, to ScriptBuilders.