Sort stability: Difference between revisions
→{{header|REXX}}: replace the wrong program
(add task to aarch64 assembly raspberry pi) |
Walterpachl (talk | contribs) (→{{header|REXX}}: replace the wrong program) |
||
(16 intermediate revisions by 13 users not shown) | |||
Line 29:
(This [[wp:Stable_sort#Comparison_of_algorithms|Wikipedia table]] shows the stability of some common sort routines).
<br><br>
=={{header|11l}}==
11l's in-built <code>sorted</code> function as well as the <code>sort</code> method of arrays are not guaranteed stable.
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program
/* use merge sort and pointer table */
/* but use a extra table of pointer for the merge */
/*******************************************/
/* Constantes file */
Line 72 ⟶ 77:
.align 4
TableCities:
.quad szUK
.quad szFR
.quad szUS
.quad szUK
.quad szUS
.quad szUS
/* pointers table */
ptrTableCities: .quad e1
.
.quad e3
.quad e4
.quad e5
.quad e6
.equ NBELEMENTS, (. - ptrTableCities) / 8
/*********************************/
/* UnInitialized data */
Line 93 ⟶ 103:
.bss
sZoneConv: .skip 24
/*********************************/
/* code section */
Line 100 ⟶ 110:
.global main
main: // entry of program
ldr x0,
bl displayTable
ldr x0,qAdrszMessSortName
bl affichageMess
ldr x0,
mov x1,0 // not use in routine
mov x2,NBELEMENTS -
mov x3,#city_name // sort by city name
mov x4,#'A' // alphanumeric
ldr x5,
bl
ldr x0,
bl displayTable
Line 119 ⟶ 129:
bl affichageMess
ldr x0,
mov x1,0 // not use in routine
mov x2,NBELEMENTS -
mov x3,#city_country // sort by city country
mov x4,#'A' // alphanumeric
ldr x5,
bl
ldr x0,
bl displayTable
Line 139 ⟶ 149:
qAdrTableCities: .quad TableCities
qAdrszMessSortName: .quad szMessSortName
qAdrptrTableExtraSort: .quad ptrTableExtraSort
qAdrszMessSortCountry: .quad szMessSortCountry
/******************************************************************/
/* merge sort
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the index of first element
/* x2 contains the number of element */
/* x3 contains the offset of area sort */
/* x4 contains the type of area sort N numeric A alpha */
/* x5 contains address extra area */
mergeSort:
stp
stp x4,x5,[sp,-16]!
stp x6,x7,[sp,-16]!
stp x8,x9,[sp,-16]!
stp x10,x11,[sp,-16]!
mov
mov
mov
ble 100f
add x9,x2,x1
lsr x9,x9,1 // number of element of each subset
mov x2,x9
bl mergeSort
add x1,x1,1
mov
bl
add x10,x9,1
1:
sub x1,x10,1
sub x8,x10,1
ldr x2,[x0,x1,lsl 3]
str x2,[x5,x8,lsl 3]
sub x10,x10,1
cmp x10,x6
bgt 1b
mov x10,x9
2:
add x1,x10,1
add x8,x7,x9
sub x8,x8,x10
ldr x2,[x0,x1,lsl 3]
str x2,[x5,x8,lsl 3]
add x10,x10,1
cmp x10,x7
blt 2b
mov x10,x6 //k
mov x1,x6 // i
mov x2,x7 // j
3:
mov x0,x5 // table address x1 = i x2 = j x3 = area sort offeset
bl comparArea
cmp x0,0
blt 4f
cmp x1,x9
b 5f
4:
mov x0,x5
ldr x6,[x5,x1, lsl 3]
str x6,[x11,x10, lsl 3]
add x1,x1,1
b 6f
5:
mov x0,x5
ldr x6,[x5,x2, lsl 3]
str x6,[x11,x10, lsl 3]
sub x2,x2,1
6:
add x10,x10,1
cmp x10,x7
ble 3b
mov x0,x11
100:
ldp x10,x11,[sp],16 // restaur 2 registers
ldp x8,x9,[sp],16 // restaur 2 registers
ldp x6,x7,[sp],16 // restaur 2 registers
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x3,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* comparison sort area */
Line 217 ⟶ 251:
stp x6,x7,[sp,-16]! // save registers
stp x8,x9,[sp,-16]! // save registers
ldr
beq 1f
cmp x6,x7 //
blt 10f
bgt 11f
b 12f
1: // else
mov x8,#0
2:
ldrb w9,[x6,x8] // byte string 1
ldrb
cmp w9,
bgt 11f
blt 10f
Line 242 ⟶ 273:
cmp w9,#0 // end string 1
beq 12f // end comparaison
add x8,x8,#1 // else add 1
b 2b // and loop
Line 254 ⟶ 285:
mov x0,0
100:
ldp x8,x9,[sp],16 // restaur 2 registers
ldp x6,x7,[sp],16 // restaur 2 registers
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
Line 297 ⟶ 303:
mov x2,x0 // table address
mov x3,0
1: // loop display table
ldr x6,[x2,x4] // load pointer
ldr x1,[
ldr x0,qAdrsMessResult
bl strInsertAtCharInc // put name in message
ldr x1,[x6,city_country] // and put country in the message
bl strInsertAtCharInc // insert result at @ character
bl affichageMess // display message
add x3,x3,1
cmp x3,#NBELEMENTS
ldr x0,qAdrszCarriageReturn
bl affichageMess
Line 325 ⟶ 328:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
<pre>
Name : London country : UK
Line 351 ⟶ 353:
Name : Paris country : US
</pre>
=={{header|Ada}}==
[[Ada 83]] and [[Ada 95]] do not provide a standard sort utility.
Line 373 ⟶ 376:
The task description doesn't specify what form the "table" takes, but here it's assumed to be a tab-delimited text.
<
US New York
US Birmingham
Line 382 ⟶ 385:
set stableSortedOnColumn1 to (do shell script ("sort -st'" & tab & "' -k1,1 <<<" & quoted form of aTable))
return "Stable sorted on column 2:" & (linefeed & stableSortedOnColumn2) & (linefeed & linefeed & ¬
"Stable sorted on column 1:") & (linefeed & stableSortedOnColumn1)</
{{output}}
<
US Birmingham
UK Birmingham
Line 396 ⟶ 399:
US New York
US Birmingham"
</syntaxhighlight>
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">records: @[
#[country: "UK", city: "London"]
#[country: "US", city: "New York"]
#[country: "US", city: "Birmingham"]
#[country: "UK", city: "Birmingham"]
]
print "Original order:"
loop records => print
print "\nSorted by country name:"
loop sort.by:'country records => print
print "\nSorted by city name:"
loop sort.by:'city records => print</syntaxhighlight>
{{out}}
<pre>Original order:
[country:UK city:London]
[country:US city:New York]
[country:US city:Birmingham]
[country:UK city:Birmingham]
Sorted by country name:
[country:UK city:London]
[country:UK city:Birmingham]
[country:US city:New York]
[country:US city:Birmingham]
Sorted by city name:
[country:US city:Birmingham]
[country:UK city:Birmingham]
[country:UK city:London]
[country:US city:New York]</pre>
=={{header|AutoHotkey}}==
Autohotkey has got a build-in sorting method for tables, which is stable.
<
(
UK, London
Line 439 ⟶ 480:
ButtonSortCities:
LV_ModifyCol(3, "Sort")
Return</
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f SORT_STABILITY.AWK [-v width=x] -v field=x SORT_STABILITY.TXT
#
Line 470 ⟶ 511:
exit(0)
}
</syntaxhighlight>
<p>input:</p>
<pre>
Line 547 ⟶ 588:
These functions use merge sort algorithm.
The sorting algorithm will be stable as long as the given function returns true for values considered equal:
<
{"US", "New York"},
{"US", "Birmingham"},
Line 555 ⟶ 596:
IO.inspect Enum.sort(cities, fn a,b -> elem(a,0) >= elem(b,0) end)
IO.inspect Enum.sort_by(cities, fn {country, _city} -> country end)
IO.inspect Enum.sort_by(cities, fn {_country, city} -> city end)</
{{out}}
<pre>
Line 565 ⟶ 606:
'''Note:''' If the function does not return true, the sorting is not stable and the order of equal terms may be shuffled:
<
{{out}}
<pre>
Line 582 ⟶ 623:
=={{header|Fortran}}==
The language does not offer an in-built sort facility. Numerous libraries exist, which may or may not have documentation on their sort routine's stability.
=={{header|FreeBASIC}}==
The language does not offer an in-built sort facility. Numerous libraries exist, which may or may not have documentation on their sort routine's stability.
=={{header|GAP}}==
<
# However, SortingPerm is stable. We will see it on an example, showing indexes of elements after the sort.
Line 601 ⟶ 645:
PrintArray(TransposedMat(List([1 .. n], i -> [a[i], b[i]])));
# [ [ 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B' ],
# [ 1, 2, 4, 8, 11, 13, 14, 16, 19, 3, 5, 6, 7, 9, 10, 12, 15, 17, 18, 20 ] ]</
=={{header|Go}}==
Line 612 ⟶ 656:
{{trans|Java}}
{{works with|Groovy|1.8.1}}
<
[
'Sort by city': { city -> city[4..-1] },
Line 621 ⟶ 665:
println "\nAfter ${label}"
cityList.sort(false, orderBy).each{ println it }
}</
Output:
Line 666 ⟶ 710:
The following sample demonstrates Java's sort stability:
<
import java.util.Comparator;
Line 712 ⟶ 756:
System.out.println();
}
}</
;Output
<pre>
Line 745 ⟶ 789:
At the time of writing this is already implemented in in Node.js and in the JS interpreters of all major browsers, including Microsoft Edge, but not according to the Mozilla implementations table, the older Internet Explorer. In earlier interpreters, sort stability depends on particular implementations.
<
print(ary);
Line 751 ⟶ 795:
print(ary);
/* a stable sort will output ["US", "Birmingham"] before ["UK", "Birmingham"] */</
Stable implementations:
Line 771 ⟶ 815:
As of January 18, 2016 (Commit SHA 7835a72), the builtin sorting filters (notably sort/0 and sort_by/1) are stable; prior to that, stability was platform-dependent. This means that stability is NOT guaranteed in jq 1.5 or earlier. In the following, a version of jq with sorting stability has been used.
<
["US", "New York"],
["US", "Birmingham"],
["UK", "Birmingham"]]
| sort_by(.[1])</
Invocation:
Line 797 ⟶ 841:
=={{header|Kotlin}}==
The collections in Kotlin's standard library are thin wrappers around the corresponding JDK collections and, since the latter's sort methods are stable, so too are Kotlin's standard sort functions.
<
fun main(args: Array<String>) {
Line 806 ⟶ 850:
// sort by city
println("By city : ${cities.sortedBy { it.drop(3) } }")
}</
{{out}}
Line 818 ⟶ 862:
Arrays can be sorted in two “built in" ways in Lasso:
<
array->sort
Line 825 ⟶ 869:
//The array can also be ordered by multiple values:
with i in array order by #i->second, #i->first do => { … } </
Sorting of arrays by either method uses “Qucksort” and is therefore unstable. A simulation of increasing sort stability would be introduced with additional params such as the example of ordering by the second then the first pair values in the example above - but would not be guaranteed stable.
Line 832 ⟶ 876:
Sort by second value only:
<
with i in #a order by #i->second do => {^ #i->first+' - '+#i->second+'\r' ^}</
{{out}}
<pre>US - Birmingham
Line 841 ⟶ 885:
Sort by second then by first:
<
with i in #a order by #i->second, #i->first do => {^ #i->first+' - '+#i->second+'\r' ^}</
{{out}}
<pre>UK - Birmingham
Line 855 ⟶ 899:
Here's an example showing that SORT indeed unstable.
<syntaxhighlight lang="lb">
randomize 0.5
N=15
Line 884 ⟶ 928:
end if
next
</syntaxhighlight>
{{Out}}
<pre>
Line 931 ⟶ 975:
Here is the stable sort
<syntaxhighlight lang="m2000 interpreter">
Module Stable {
Inventory queue alfa
Line 959 ⟶ 1,003:
US Birmingham
</syntaxhighlight>
Line 965 ⟶ 1,009:
We can sort in on key only. Lets make keys with two fields (based on fields lengths, except for last one)
<syntaxhighlight lang="m2000 interpreter">
Module Stable1 {
Inventory queue alfa
Line 993 ⟶ 1,037:
US New York
</syntaxhighlight>
Now second column is sorting (but it is one column all, no two columns). So lets see the unstable sort. Because all keys now are unique we just remove queue from Inventory definition.
<syntaxhighlight lang="m2000 interpreter">
Module Stable2 {
Inventory alfa
Line 1,024 ⟶ 1,068:
US New York
</syntaxhighlight>
So now we see that using unique keys in either type of inventories we get same output.
Line 1,034 ⟶ 1,078:
If we delete a key in normal inventory we miss the sort order. We can't delete keys in queue inventories, but we can drop from the last append a number of keys. Also Exist() function in queue inventories always find the last entry (for same keys), until that dropped, so with next use of Exist(pointer_to_inventory, key_case_sensitive$) we find the previous one. We can use keys as numbers, but they stored as strings.
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Sort is not always stable. Ordering, which gives a list of indices such as to put the elements of the list in order, is stable. An example would be to sort the list (of lists) {{1, 2, 3}, {4, 5, 6}, {5, 4, 3}, {9, 5, 1}}, and doing so by looking at the 2nd value of each list:
<
Sort[mylist, (#1[[2]] < #2[[2]]) &]
#[[Ordering[#[[All, 2]]]]] &[mylist]</
gives:
<
{{1, 2, 3}, {5, 4, 3}, {4, 5, 6}, {9, 5, 1}}</
Showing that Sort is unstable, and that by using input[[Ordering[input]]] Ordering provides a way to make a stable sort.
Line 1,050 ⟶ 1,094:
Java's [http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List) Collections.sort()] and [http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#sort(java.lang.Object%5B%5D) Arrays.sort()] methods are guaranteed stable. The following sample takes advantage of this to demonstrate sort stability.
<
options replace format comments java crossref savelog symbols nobinary
Line 1,105 ⟶ 1,149:
method compare(lft = Object, rgt = Object) public binary returns int
return (String lft).substring(0, 2).compareTo((String rgt).substring(0, 2))
</syntaxhighlight>
;Output
<pre>
Line 1,135 ⟶ 1,179:
=={{header|Nim}}==
Default Nim sort in the algorithm module is stable.
<syntaxhighlight lang="nim">import algorithm
const Records = [(country: "UK", city: "London"),
(country: "US", city: "New York"),
(country: "US", city: "Birmingham"),
(country: "UK", city: "Birmingham")]
echo "Original order:"
for record in Records:
echo record.country, " ", record.city
echo()
echo "Sorted by city name:"
for record in Records.sortedByIt(it.city):
echo record.country, " ", record.city
echo()
echo "Sorted by country name:"
for record in Records.sortedByIt(it.country):
echo record.country, " ", record.city</syntaxhighlight>
{{out}}
<pre>Original order:
UK London
US New York
US Birmingham
UK Birmingham
Sorted by city name:
US Birmingham
UK Birmingham
UK London
US New York
Sorted by country name:
UK London
UK Birmingham
US New York
US Birmingham</pre>
=={{header|OCaml}}==
Line 1,141 ⟶ 1,224:
=={{header|ooRexx}}==
Open Object Rexx provides sort methods (<code>sort</code> and <code>sortWith(comparator)</code>) for its collection classes. By default these sort methods are implemented via an unstable <em>Quicksort</em> algorithm but the language does provide stable sorting methods (<code>stableSort</code> and <code>stableSortWith(comparator)</code>) implemented via a stable <em>Mergesort</em> algorithm.
<
Do
cities = .array~of('UK London', 'US New York', 'US Birmingham', 'UK Birmingham',)
Line 1,184 ⟶ 1,267:
End
Exit
</syntaxhighlight>
;Output
<pre>
Line 1,225 ⟶ 1,308:
=={{header|OpenEdge/Progress}}==
The results can be forced to stable by ''additionally'' sorting on the ROWID of the record. If you leave the additional sort out, the indexes on the temp-table can influence the result.
<
FIELD country AS CHAR FORMAT 'x(2)'
FIELD city AS CHAR FORMAT 'x(16)'
Line 1,249 ⟶ 1,332:
MESSAGE
cc[1] SKIP(1) cc[2]
VIEW-AS ALERT-BOX.</
'''Output:'''
Line 1,279 ⟶ 1,362:
Example:
<
Cities = ['UK'#'London'
'US'#'New York'
Line 1,289 ⟶ 1,372:
%% sort by country; NOT stable because '<' is not reflexiv
{Show {Sort Cities fun {$ A B} A.1 < B.1 end}}</
=={{header|PARI/GP}}==
Line 1,299 ⟶ 1,382:
=={{header|Perl}}==
The stability of Perl's in-built [http://perldoc.perl.org/functions/sort.html sort] function is version-dependent. If you want to guarantee a stable sort from it, you should use the following [http://perldoc.perl.org/sort.html sort pragma]:
<syntaxhighlight lang
=={{header|Phix}}==
The standard sort method is merge sort, which is apparently stable, though I would be reluctant to guarantee that, or rely on it, especially given that a simple tag sort is irrefutably stable since it explicitly orders by tag (aka original position) within any equal keys.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"UK"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"London"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"US"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"New York"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"US"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Birmingham"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"UK"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Birmingham"</span><span style="color: #0000FF;">}}</span>
<span style="color: #000080;font-style:italic;">---------------------
-- probably stable --
---------------------</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">cmp</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmp</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)),{</span><span style="color: #004600;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #000080;font-style:italic;">-----------------------
-- guaranteed stable --
-----------------------</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">tag_cmp</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- (see note)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">c</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tag_cmp</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">shuffle</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)))</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tags</span><span style="color: #0000FF;">),{</span><span style="color: #004600;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{Out}}
<pre>
{{
{
{
{
{{`US`, `Birmingham`},
{
{`UK`, `London`},
{
</pre>
Of course test=sort(test) guarantees alphabetical on second column within matching first column. Lastly, preserving a primary tag sort ordering within a secondary tag sort is a bit more mind-bending, but even that is not particularly difficult.
=={{header|PHP}}==
Line 1,355 ⟶ 1,437:
=={{header|Python}}==
Python's in-built [http://docs.python.org/library/functions.html#sorted sorted] function as well as the [http://docs.python.org/library/stdtypes.html#mutable-sequence-types sort method of lists] are guaranteed stable (since version 2.3). (For even more information on the underlying routine, [[wp:timsort]], see [http://svn.python.org/projects/python/trunk/Objects/listsort.txt this]).
=={{header|Quackery}}==
The inbuilt sort is stable.
=={{header|R}}==
R uses shell sort (stable) or quick sort (unstable). An easy way to show the difference is names to vector entries, then check if names are still ordered after sorting.
<syntaxhighlight lang="r">
# First, define a bernoulli sample, of length 26.
x <- sample(c(0, 1), 26, replace=T)
Line 1,382 ⟶ 1,469:
# e h j n q s u x z a b c d f g i k l m o p r t v w y
# 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
</syntaxhighlight>
=={{header|Racket}}==
Line 1,388 ⟶ 1,475:
Racket comes with a standard <tt>sort</tt> function, which is documented [[http://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Fprivate%2Flist..rkt%29._sort%29%29 here]]. It is documented as stable.
<syntaxhighlight lang="racket">
#lang racket
Line 1,406 ⟶ 1,493:
;; -> '(("US" "Birmingham") ("UK" "Birmingham")
;; ("UK" "London") ("US" "New York"))
</syntaxhighlight>
=={{header|Raku}}==
Line 1,414 ⟶ 1,501:
Short demonstration for sorting only on the second item of each array:
<syntaxhighlight lang="raku"
my @cities =
['UK', 'London'],
Line 1,422 ⟶ 1,509:
;
.say for @cities.sort: { .[1] };</
=={{header|REBOL}}==
<
blk: [
Line 1,442 ⟶ 1,529:
UK Birmingham
]
sort/skip/compare blk 2 func [a b] [either a < b [-1] [either a > b [1] [0]]]</
=={{header|REXX}}==
<syntaxhighlight lang="rexx"></syntaxhighlight>
call
call show 'before
call stableSort
exit
/*----------------------------------------------------------------------------*/
stableSort: procedure expose a.
parse Value '' With l1 l2
Do i=1 To a.0
parse Var a.i f1 f2
f2=translate(f2,'_',' ')
If pos(f1,l1)=0 Then l1=l1 f1
If pos(f2,l2)=0 Then l2=l2 f2
End
l1=wordsort(l1)
l2=wordsort(l2)
Say ''
Say 'sorted by country'
Do While l1<>''
Parse Var l1 f1s l1
Do i=1 To a.0
parse Var a.i f1 f2
If f1=f1s Then
Say a.i
End
End
Say ''
Say 'sorted by city'
Do While l2<>''
Parse Var l2 f2s l2
Do i=1 To a.0
parse Var a.i f1 f2
If translate(f2,'_',' ')=f2s Then
Say a.i
End
End
/*---------------------------------------------------------------------------------*/
gena: a.0=0
Call store 'UK London'
Call store 'US New York'
Call store 'US Birmingham'
Call store 'UK Birmingham'
Return
store:
z=a.0+1
a.z=arg(1)
a.0=z
Return
show:
Say arg(1)
do i=1 To a.0
say a.i
End
Return
wordsort: Procedure
/**********************************************************************
* Sort the list of words supplied as argument. Return the sorted list
**********************************************************************/
Parse Arg wl
wa.=''
wa.0=0
Do While wl<>''
Parse Var wl w wl
Do i=1 To wa.0
If wa.i>w Then Leave
End
If i<=wa.0 Then Do
Do j=wa.0 To i By -1
ii=j+1
wa.ii=wa.j
End
End
wa.i=w
wa.0=wa.0+1
End
swl=''
Do i=1 To wa.0
swl=swl wa.i
End
Return strip(swl)</syntaxhighlight>
{{out|output|text= when using the default list:}}
<pre>
K:\>rexx sso
UK London
US New York
US Birmingham
sorted by country
UK London
UK Birmingham
US New York
US Birmingham
sorted by city
US Birmingham
UK Birmingham
UK London
US New York
</pre>
=={{header|Ring}}==
<
aList = [["UK", "London"],
["US", "New York"],
Line 1,489 ⟶ 1,644:
["UK", "Birmingham"]]
see sort(aList,2)
</syntaxhighlight>
=={{header|Ruby}}==
Line 1,495 ⟶ 1,650:
{{works with|MRI|1.8.7, 1.9.2}}
<
["US", "New York"],
["US", "Birmingham"],
Line 1,501 ⟶ 1,656:
p ary.sort {|a,b| a[1] <=> b[1]}
# MRI reverses the Birminghams:
# => [["UK", "Birmingham"], ["US", "Birmingham"], ["UK", "London"], ["US", "New York"]]</
Other implementations of Ruby might differ. Old versions of [[JRuby]] used java.util.Arrays.sort, which was a stable sort, but was slower than MRI. To increase performance, JRuby switched to quicksort, which is not stable. [http://jira.codehaus.org/browse/JRUBY-2198 (3)]
Line 1,508 ⟶ 1,663:
To code a stable sort, without implementing another sorting algorithm (such as [[Sorting algorithms/Merge sort|merge sort]]), use a Schwartzian transform.
<
def stable_sort
n = -1
Line 1,527 ⟶ 1,682:
sort_by {|x| n += 1; [(yield x), n]}
end
end</
<
["US", "New York"],
["US", "Birmingham"],
Line 1,536 ⟶ 1,691:
# => [["US", "Birmingham"], ["UK", "Birmingham"], ["UK", "London"], ["US", "New York"]]
p ary.stable_sort_by {|x| x[1]}
# => [["US", "Birmingham"], ["UK", "Birmingham"], ["UK", "London"], ["US", "New York"]]</
=={{header|Rust}}==
Rust's builtin sorts (.sort(), .sort_by(...), .sort_by_key(...)) are all stable
<
let country_city = [
("UK", "London"),
Line 1,569 ⟶ 1,724:
println!("{} {}", x.0, x.1);
}
}</
Output: <pre>Original:
Line 1,597 ⟶ 1,752:
Examples:
<
list: List[(Int, Char)] = List((1,c), (1,b), (2,a))
Line 1,615 ⟶ 1,770:
scala> cities.sortBy(_ substring 4)
res47: Seq[String] = ArrayBuffer(US Birmingham, UK Birmingham, UK London, US New York)</
Besides that, there is the object <tt>scala.util.Sorting</tt>, which provides <tt>quickSort</tt> and <tt>stableSort</tt>. The former is only provided on <tt>Array</tt>, but the latter is provided over both <tt>Array</tt> and <tt>Seq</tt>. These sorts operate in-place, with the one over <tt>Seq</tt> returning a sorted <tt>Array</tt>. Here is one example:
<
cityArray: Array[String] = Array(UK London, US New York, US Birmingham, UK Birmingham)
Line 1,623 ⟶ 1,778:
scala> cityArray
res56: Array[String] = Array(US Birmingham, UK Birmingham, UK London, US New York)</
=={{header|Sidef}}==
Sidef uses the stable merge-sort algorithm for sorting an array.
<
<UK London>,
<US New\ York>,
Line 1,636 ⟶ 1,791:
table.sort {|a,b| a[0] <=> b[0]}.each { |col|
say "#{col[0]} #{col[1]}"
}</
{{out}}
<pre>UK London
Line 1,651 ⟶ 1,806:
=={{header|TXR}}==
TXR provides a number of sorting functions. <code>sort</code> and <code>nsort</code> (destructive variant) are not stable for vectors and strings, but are stable for lists.
The functions <code>ssort</code> and <code>snsort</code> counterparts are stable for all sequence kinds.
In addition, there are caching variants of all these functions: <code>csort</code>, <code>cnsort</code>, <code>cssort</code> and <code>csnsort</code>. They respectively have the same stability properties as their counterparts without the leading <code>c</code>.
TXR Lisp originally had one sorting function called <code>sort</code>, which was destructive, like the <code>sort</code> in Common Lisp. That function was renamed to <code>nsort</code>, and <code>sort</code> became the name of a non-destructive function. That happened in TXR 238, released in May, 2020.
=={{header|Wren}}==
Line 1,660 ⟶ 1,819:
Below we illustrate the points made in the task description using the stable insertion sort.
<
var data = [ ["UK", "London"], ["US", "New York"], ["US", "Birmingham"], ["UK", "Birmingham"] ]
Line 1,681 ⟶ 1,840:
var data3 = data.toList
Sort.insertion(data3, cmp2)
System.print(" " + data3.join("\n "))</
{{out}}
Line 1,703 ⟶ 1,862:
[US, New York]
</pre>
=={{header|XPL0}}==
There is no built-in sort routine in XPL0. The 32-bit versions are
distributed with xpllib, which provides an integer sort routine. This
uses the Quicksort algorithm, which is unstable.
=={{header|zkl}}==
zkl's sort methods don't mention stability or columns, they are comparison based.
<
{ list.sort('wrap(city1,city2){ city1[col]<city2[col] }) }</
<
T("UK", "London"), T("US", "New York"),
T("US", "Birmingham"),T("UK", "Birmingham"), );
sortByColumn(cities,0).concat("\n").println("\n------");
sortByColumn(cities,1).concat("\n").println();</
{{out}}
<pre>
|