Sorting algorithms/Selection sort

From Rosetta Code
Revision as of 20:25, 25 July 2021 by Petelomax (talk | contribs) (→‎{{header|Phix}}: only move when needed)
Task
Sorting algorithms/Selection sort
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Sort an array (or list) of elements using the Selection sort algorithm.


It works as follows:

First find the smallest element in the array and exchange it with the element in the first position, then find the second smallest element and exchange it with the element in the second position, and continue in this way until the entire array is sorted.


Its asymptotic complexity is   O(n2)   making it inefficient on large arrays.

Its primary purpose is for when writing data is very expensive (slow) when compared to reading, eg. writing to flash memory or EEPROM.

No other sorting algorithm has less data movement.


References



11l

Translation of: Python

<lang 11l>F selection_sort(&lst)

  L(e) lst
     V mn = min(L.index .< lst.len, key' x -> @lst[x])
     (lst[L.index], lst[mn]) = (lst[mn], e)

V arr = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0] selection_sort(&arr) print(arr)</lang>

Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

360 Assembly

Translation of: PL/I

The program uses ASM structured macros and two ASSIST macros to keep the code as short as possible. <lang 360asm>* Selection sort 26/06/2016 SELECSRT CSECT

        USING  SELECSRT,R13       base register
        B      72(R15)            skip savearea
        DC     17F'0'             savearea
        STM    R14,R12,12(R13)    prolog
        ST     R13,4(R15)         "
        ST     R15,8(R13)         " 
        LR     R13,R15            "
        LA     RJ,1               j=1
        DO WHILE=(C,RJ,LE,N)      do j=1 to n
        LR     RK,RJ                k=j
        LR     R1,RJ                j
        SLA    R1,2                 .
        LA     R3,A-4(R1)           @a(j)   
        L      RT,0(R3)             temp=a(j)   
        LA     RI,1(RJ)             i=j+1
        DO WHILE=(C,RI,LE,N)        do i=j+1 to n
        LR     R1,RI                  i
        SLA    R1,2                   .
        L      R2,A-4(R1)             a(i)
        IF CR,RT,GT,R2 THEN           if temp>a(i) then
        LR     RT,R2                    temp=a(i)
        LR     RK,RI                    k=i
        ENDIF  ,                      end if
        LA     RI,1(RI)               i=i+1
        ENDDO  ,                    end do

L R0,0(R3) a(j)

        LR     R1,RK                k
        SLA    R1,2                 .
        ST     R0,A-4(R1)           a(k)=a(j)
        ST     RT,0(R3)             a(j)=temp;
        LA     RJ,1(RJ)             j=j+1
        ENDDO  ,                  end do
        LA     R3,PG              pgi=0
        LA     RI,1               i=1
        DO     WHILE=(C,RI,LE,N)  do i=1 to n
        LR     R1,RI                i
        SLA    R1,2                 .
        L      R2,A-4(R1)           a(i)
        XDECO  R2,XDEC              edit a(i)
        MVC    0(4,R3),XDEC+8       output a(i)
        LA     R3,4(R3)             pgi=pgi+4
        LA     RI,1(RI)             i=i+1
        ENDDO  ,                  end do
        XPRNT  PG,L'PG            print buffer
        L      R13,4(0,R13)       epilog 
        LM     R14,R12,12(R13)    "
        XR     R15,R15            "
        BR     R14                exit

A DC F'4',F'65',F'2',F'-31',F'0',F'99',F'2',F'83',F'782',F'1'

     DC F'45',F'82',F'69',F'82',F'104',F'58',F'88',F'112',F'89',F'74'

N DC A((N-A)/L'A) number of items of a PG DC CL80' ' buffer XDEC DS CL12 temp for xdeco

        YREGS

RI EQU 6 i RJ EQU 7 j RK EQU 8 k RT EQU 9 temp

        END    SELECSRT</lang>
Output:
 -31   0   1   2   2   4  45  58  65  69  74  82  82  83  88  89  99 104 112 782

AArch64 Assembly

Works with: as version Raspberry Pi 3B version Buster 64 bits

<lang AArch64 Assembly> /* ARM assembly AARCH64 Raspberry PI 3B */ /* program selectionSort64.s */

/*******************************************/ /* Constantes file */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeConstantesARM64.inc"

/*********************************/ /* Initialized data */ /*********************************/ .data szMessSortOk: .asciz "Table sorted.\n" szMessSortNok: .asciz "Table not sorted !!!!!.\n" sMessResult: .asciz "Value  : @ \n" szCarriageReturn: .asciz "\n"

.align 4

  1. TableNumber: .quad 1,3,6,2,5,9,10,8,4,7

TableNumber: .quad 10,9,8,7,6,5,4,3,2,1

                .equ NBELEMENTS, (. - TableNumber) / 8 

/*********************************/ /* UnInitialized data */ /*********************************/ .bss sZoneConv: .skip 24 /*********************************/ /* code section */ /*********************************/ .text .global main main: // entry of program

   ldr x0,qAdrTableNumber                         // address number table
   mov x1,0
   mov x2,NBELEMENTS                              // number of élements 
   bl selectionSort
   ldr x0,qAdrTableNumber                         // address number table
   bl displayTable

   ldr x0,qAdrTableNumber                         // address number table
   mov x1,NBELEMENTS                              // number of élements 
   bl isSorted                                    // control sort
   cmp x0,1                                       // sorted ?
   beq 1f                                    
   ldr x0,qAdrszMessSortNok                       // no !! error sort
   bl affichageMess
   b 100f

1: // yes

   ldr x0,qAdrszMessSortOk
   bl affichageMess

100: // standard end of the program

   mov x0,0                                       // return code
   mov x8,EXIT                                    // request to exit program
   svc 0                                          // perform the system call

qAdrsZoneConv: .quad sZoneConv qAdrszCarriageReturn: .quad szCarriageReturn qAdrsMessResult: .quad sMessResult qAdrTableNumber: .quad TableNumber qAdrszMessSortOk: .quad szMessSortOk qAdrszMessSortNok: .quad szMessSortNok /******************************************************************/ /* control sorted table */ /******************************************************************/ /* x0 contains the address of table */ /* x1 contains the number of elements > 0 */ /* x0 return 0 if not sorted 1 if sorted */ isSorted:

   stp x2,lr,[sp,-16]!              // save  registers
   stp x3,x4,[sp,-16]!              // save  registers
   mov x2,0
   ldr x4,[x0,x2,lsl 3]

1:

   add x2,x2,1
   cmp x2,x1
   bge 99f
   ldr x3,[x0,x2, lsl 3]
   cmp x3,x4
   blt 98f
   mov x4,x3
   b 1b

98:

   mov x0,0                       // not sorted
   b 100f

99:

   mov x0,1                       // sorted

100:

   ldp x3,x4,[sp],16              // restaur  2 registers
   ldp x2,lr,[sp],16              // restaur  2 registers
   ret                            // return to address lr x30

/******************************************************************/ /* selection sort */ /******************************************************************/ /* x0 contains the address of table */ /* x1 contains the first element */ /* x2 contains the number of element */ selectionSort:

   stp x1,lr,[sp,-16]!              // save  registers
   stp x2,x3,[sp,-16]!              // save  registers
   stp x4,x5,[sp,-16]!              // save  registers
   stp x6,x7,[sp,-16]!              // save  registers
   mov x3,x1                        // start index i
   sub x7,x2,1                      // compute n - 1

1: // start loop

   mov x4,x3
   add x5,x3,1                      // init index 2

2:

   ldr x1,[x0,x4,lsl 3]             // load value A[mini]
   ldr x6,[x0,x5,lsl 3]             // load value A[j]
   cmp x6,x1                        // compare value
   csel x4,x5,x4,lt                 // j -> mini
   add x5,x5,1                      // increment index j
   cmp x5,x2                        // end ?
   blt 2b                           // no -> loop
   cmp x4,x3                        // mini <> j ?
   beq 3f                           // no
   ldr x1,[x0,x4,lsl 3]             // yes swap A[i] A[mini]
   ldr x6,[x0,x3,lsl 3]
   str x1,[x0,x3,lsl 3]
   str x6,[x0,x4,lsl 3]

3:

   add x3,x3,1                      // increment i
   cmp x3,x7                        // end ?
   blt 1b                           // no -> loop 

100:

   ldp x6,x7,[sp],16                // restaur  2 registers
   ldp x4,x5,[sp],16                // restaur  2 registers
   ldp x2,x3,[sp],16                // restaur  2 registers
   ldp x1,lr,[sp],16                // restaur  2 registers
   ret                              // return to address lr x30

/******************************************************************/ /* Display table elements */ /******************************************************************/ /* x0 contains the address of table */ displayTable:

   stp x1,lr,[sp,-16]!              // save  registers
   stp x2,x3,[sp,-16]!              // save  registers
   mov x2,x0                        // table address
   mov x3,0

1: // loop display table

   ldr x0,[x2,x3,lsl 3]
   ldr x1,qAdrsZoneConv
   bl conversion10                  // décimal conversion
   ldr x0,qAdrsMessResult
   ldr x1,qAdrsZoneConv
   bl strInsertAtCharInc            // insert result at @ character
   bl affichageMess                 // display message
   add x3,x3,1
   cmp x3,NBELEMENTS - 1
   ble 1b
   ldr x0,qAdrszCarriageReturn
   bl affichageMess

100:

   ldp x2,x3,[sp],16               // restaur  2 registers
   ldp x1,lr,[sp],16               // restaur  2 registers
   ret                             // return to address lr x30

/********************************************************/ /* File Include fonctions */ /********************************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeARM64.inc" </lang>

ActionScript

<lang ActionScript>function selectionSort(input: Array):Array { //find the i'th element for (var i:uint = 0; i < input.length; i++) { //set minIndex to an arbitrary value var minIndex:uint=i; //find the smallest number for (var j:uint = i; j < input.length; j++) { if (input[j]<input[minIndex]) { minIndex=j; } } //swap the smallest number into place var tmp:Number=input[i]; input[i]=input[minIndex]; input[minIndex]=tmp; } return input; }</lang>

Ada

<lang ada>with Ada.Text_IO; use Ada.Text_IO;

procedure Test_Selection_Sort is

  type Integer_Array is array (Positive range <>) of Integer;
  procedure Sort (A : in out Integer_Array) is
     Min  : Positive;
     Temp : Integer;
  begin
     for I in A'First..A'Last - 1 loop
        Min := I;
        for J in I + 1..A'Last loop
           if A (Min) > A (J) then
              Min := J;
           end if;
        end loop;
        if Min /= I then
           Temp    := A (I);
           A (I)   := A (Min);
           A (Min) := Temp;
        end if;
     end loop;
  end Sort;
  A : Integer_Array := (4, 9, 3, -2, 0, 7, -5, 1, 6, 8);

begin

  Sort (A);
  for I in A'Range loop
     Put (Integer'Image (A (I)) & " ");
  end loop;

end Test_Selection_Sort;</lang>

Output:
-5 -2  0  1  3  4  6  7  8  9

ALGOL 68

Translation of: Ada
Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386

<lang algol68>MODE DATA = REF CHAR;

PROC in place selection sort = (REF[]DATA a)VOID: BEGIN

  INT min;
  DATA temp;
  FOR i FROM LWB a TO UPB a DO
     min := i;
     FOR j FROM i + 1 TO UPB a DO
        IF a [min] > a [j] THEN
           min := j
        FI
     OD;
     IF min /= i THEN
        temp    := a [i];
        a [i]   := a [min];
        a [min] := temp
     FI
  OD

END # in place selection sort #;

[32]CHAR data := "big fjords vex quick waltz nymph"; [UPB data]DATA ref data; FOR i TO UPB data DO ref data[i] := data[i] OD; in place selection sort(ref data); FOR i TO UPB ref data DO print(ref data[i]) OD; print(new line); print((data))</lang>

Output:
     abcdefghiijklmnopqrstuvwxyz
big fjords vex quick waltz nymph

ARM Assembly

Works with: as version Raspberry Pi

<lang ARM Assembly> /* ARM assembly Raspberry PI */ /* program selectionSort.s */

/************************************/ /* Constantes */ /************************************/ .equ STDOUT, 1 @ Linux output console .equ EXIT, 1 @ Linux syscall .equ WRITE, 4 @ Linux syscall /*********************************/ /* Initialized data */ /*********************************/ .data szMessSortOk: .asciz "Table sorted.\n" szMessSortNok: .asciz "Table not sorted !!!!!.\n" sMessResult: .ascii "Value  : " sMessValeur: .fill 11, 1, ' ' @ size => 11 szCarriageReturn: .asciz "\n"

.align 4 iGraine: .int 123456 .equ NBELEMENTS, 10

  1. TableNumber: .int 1,3,6,2,5,9,10,8,4,7

TableNumber: .int 10,9,8,7,6,5,4,3,2,1 /*********************************/ /* UnInitialized data */ /*********************************/ .bss /*********************************/ /* code section */ /*********************************/ .text .global main main: @ entry of program

1:

   ldr r0,iAdrTableNumber                         @ address number table
   mov r1,#0
   mov r2,#NBELEMENTS                             @ number of élements 
   bl selectionSort
   ldr r0,iAdrTableNumber                         @ address number table
   bl displayTable

   ldr r0,iAdrTableNumber                         @ address number table
   mov r1,#NBELEMENTS                             @ number of élements 
   bl isSorted                                    @ control sort
   cmp r0,#1                                      @ sorted ?
   beq 2f                                    
   ldr r0,iAdrszMessSortNok                       @ no !! error sort
   bl affichageMess
   b 100f

2: @ yes

   ldr r0,iAdrszMessSortOk
   bl affichageMess

100: @ standard end of the program

   mov r0, #0                                     @ return code
   mov r7, #EXIT                                  @ request to exit program
   svc #0                                         @ perform the system call

iAdrsMessValeur: .int sMessValeur iAdrszCarriageReturn: .int szCarriageReturn iAdrsMessResult: .int sMessResult iAdrTableNumber: .int TableNumber iAdrszMessSortOk: .int szMessSortOk iAdrszMessSortNok: .int szMessSortNok /******************************************************************/ /* control sorted table */ /******************************************************************/ /* r0 contains the address of table */ /* r1 contains the number of elements > 0 */ /* r0 return 0 if not sorted 1 if sorted */ isSorted:

   push {r2-r4,lr}                                    @ save registers
   mov r2,#0
   ldr r4,[r0,r2,lsl #2]

1:

   add r2,#1
   cmp r2,r1
   movge r0,#1
   bge 100f
   ldr r3,[r0,r2, lsl #2]
   cmp r3,r4
   movlt r0,#0
   blt 100f
   mov r4,r3
   b 1b

100:

   pop {r2-r4,lr}
   bx lr                                              @ return 

/******************************************************************/ /* selection sort */ /******************************************************************/ /* r0 contains the address of table */ /* r1 contains the first element */ /* r2 contains the number of element */ selectionSort:

   push {r1-r7,lr}                                        @ save registers
   mov r3,r1                                              @ start index i
   sub r7,r2,#1                                           @ compute n - 1

1: @ start loop

   mov r4,r3
   add r5,r3,#1                                           @ init index 2

2:

   ldr r1,[r0,r4,lsl #2]                                  @ load value A[mini]
   ldr r6,[r0,r5,lsl #2]                                  @ load value A[j]
   cmp r6,r1                                              @ compare value
   movlt r4,r5                                            @ j -> mini
   add r5,#1                                              @ increment index j
   cmp r5,r2                                              @ end ?
   blt 2b                                                 @ no -> loop
   cmp r4,r3                                              @ mini <> j ?
   beq 3f                                                 @ no
   ldr r1,[r0,r4,lsl #2]                                  @ yes swap A[i] A[mini]
   ldr r6,[r0,r3,lsl #2]
   str r1,[r0,r3,lsl #2]
   str r6,[r0,r4,lsl #2]

3:

   add r3,#1                                              @ increment i
   cmp r3,r7                                              @ end ?
   blt 1b                                                 @ no -> loop 

100:

   pop {r1-r7,lr}
   bx lr                                                  @ return 

/******************************************************************/ /* Display table elements */ /******************************************************************/ /* r0 contains the address of table */ displayTable:

   push {r0-r3,lr}                                    @ save registers
   mov r2,r0                                          @ table address
   mov r3,#0

1: @ loop display table

   ldr r0,[r2,r3,lsl #2]
   ldr r1,iAdrsMessValeur                             @ display value
   bl conversion10                                    @ call function
   ldr r0,iAdrsMessResult
   bl affichageMess                                   @ display message
   add r3,#1
   cmp r3,#NBELEMENTS - 1
   ble 1b
   ldr r0,iAdrszCarriageReturn
   bl affichageMess

100:

   pop {r0-r3,lr}
   bx lr

/******************************************************************/ /* display text with size calculation */ /******************************************************************/ /* r0 contains the address of the message */ affichageMess:

   push {r0,r1,r2,r7,lr}                          @ save  registres
   mov r2,#0                                      @ counter length 

1: @ loop length calculation

   ldrb r1,[r0,r2]                                @ read octet start position + index 
   cmp r1,#0                                      @ if 0 its over 
   addne r2,r2,#1                                 @ else add 1 in the length 
   bne 1b                                         @ and loop 
                                                  @ so here r2 contains the length of the message 
   mov r1,r0                                      @ address message in r1 
   mov r0,#STDOUT                                 @ code to write to the standard output Linux 
   mov r7, #WRITE                                 @ code call system "write" 
   svc #0                                         @ call systeme 
   pop {r0,r1,r2,r7,lr}                           @ restaur des  2 registres */ 
   bx lr                                          @ return  

/******************************************************************/ /* Converting a register to a decimal unsigned */ /******************************************************************/ /* r0 contains value and r1 address area */ /* r0 return size of result (no zero final in area) */ /* area size => 11 bytes */ .equ LGZONECAL, 10 conversion10:

   push {r1-r4,lr}                                 @ save registers 
   mov r3,r1
   mov r2,#LGZONECAL

1: @ start loop

   bl divisionpar10U                               @ unsigned  r0 <- dividende. quotient ->r0 reste -> r1
   add r1,#48                                      @ digit
   strb r1,[r3,r2]                                 @ store digit on area
   cmp r0,#0                                       @ stop if quotient = 0 
   subne r2,#1                                     @ else previous position
   bne 1b	                                    @ and loop
                                                   @ and move digit from left of area
   mov r4,#0

2:

   ldrb r1,[r3,r2]
   strb r1,[r3,r4]
   add r2,#1
   add r4,#1
   cmp r2,#LGZONECAL
   ble 2b
                                                     @ and move spaces in end on area
   mov r0,r4                                         @ result length 
   mov r1,#' '                                       @ space

3:

   strb r1,[r3,r4]                                   @ store space in area
   add r4,#1                                         @ next position
   cmp r4,#LGZONECAL
   ble 3b                                            @ loop if r4 <= area size

100:

   pop {r1-r4,lr}                                    @ restaur registres 
   bx lr                                             @return

/***************************************************/ /* division par 10 unsigned */ /***************************************************/ /* r0 dividende */ /* r0 quotient */ /* r1 remainder */ divisionpar10U:

   push {r2,r3,r4, lr}
   mov r4,r0                                          @ save value
   //mov r3,#0xCCCD                                   @ r3 <- magic_number lower  raspberry 3
   //movt r3,#0xCCCC                                  @ r3 <- magic_number higter raspberry 3
   ldr r3,iMagicNumber                                @ r3 <- magic_number    raspberry 1 2
   umull r1, r2, r3, r0                               @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0) 
   mov r0, r2, LSR #3                                 @ r2 <- r2 >> shift 3
   add r2,r0,r0, lsl #2                               @ r2 <- r0 * 5 
   sub r1,r4,r2, lsl #1                               @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)
   pop {r2,r3,r4,lr}
   bx lr                                              @ leave function 

iMagicNumber: .int 0xCCCCCCCD


</lang>

Arturo

<lang rebol>selectionSort: function [items][

   sorted: new []
   tmp: new items
   while [not? empty? tmp][
       minIndex: index tmp min tmp
       'sorted ++ tmp\[minIndex]
       remove 'tmp .index minIndex
   ]
   return sorted

]

print selectionSort [3 1 2 8 5 7 9 4 6]</lang>

Output:
1 2 3 4 5 6 7 8 9

AutoHotkey

ahk forum: discussion <lang AutoHotkey>MsgBox % SelecSort("") MsgBox % SelecSort("xxx") MsgBox % SelecSort("3,2,1") MsgBox % SelecSort("dog,000000,xx,cat,pile,abcde,1,cat,zz,xx,z")

SelecSort(var) {  ; SORT COMMA SEPARATED LIST

  StringSplit a, var, `,                ; make array, size = a0
  Loop % a0-1 {
     i := A_Index, mn := a%i%, j := m := i
     Loop % a0-i {                      ; find minimum
         j++
         If (a%j% < mn)
            mn := a%j%, m := j
     }
     t := a%i%, a%i% := a%m%, a%m% := t ; swap first with minimum
  }
  Loop % a0                             ; construct string from sorted array
     sorted .= "," . a%A_Index%
  Return SubStr(sorted,2)               ; drop leading comma

}</lang>

AWK

<lang awk>function getminindex(gl, gi, gs) {

 min = gl[gi]
 gm = gi
 for(gj=gi; gj <= gs; gj++) {
   if ( gl[gj] < min ) {
     min = gl[gj]
     gm = gj
   }
 }
 return gm

}

{

 line[NR] = $0

} END { # sort it with selection sort

 for(i=1; i <= NR; i++) {
   mi = getminindex(line, i, NR)
   t = line[i]
   line[i] = line[mi];
   line[mi] = t
 }
 #print it
 for(i=1; i <= NR; i++) {
   print line[i]
 }

}</lang>

BBC BASIC

<lang BBCBASIC>DEF PROC_SelectionSort(Size%) FOR I% = 1 TO Size%-1

  lowest% = I%
  FOR J% = (I% + 1) TO Size%
     IF data%(J%) < data%(lowest%) lowest% = J%
  NEXT J%
  IF I%<>lowest% SWAP data%(I%),data%(lowest%)

NEXT I% ENDPROC</lang>

BASIC

GWBASIC

Works with: QBASIC, QuickBASIC, VB-DOS <lang GWBASIC> 10 'SAVE"SELSORT",A 20 ' Selection Sort Algorithm 30 ' 40 ' VAR 50 DEFINT A-Z 60 OPTION BASE 1 70 I=0: J=0: IMINV = 0: IMAX = 0: TP! = 0: TL! = 0 80 ' 90 CLS 100 PRINT "This program does the Selection Sort Algorithm" 110 INPUT "Number of elements to sort (Max=1000, Enter=10)";IMAX 120 IF IMAX = 0 THEN IMAX = 10 130 IF IMAX > 1000 THEN IMAX = 1000 140 DIM N(IMAX) 150 ' Creates and shows the unsorted list 160 RANDOMIZE TIMER 170 FOR I=1 TO IMAX: N(I) = I: NEXT I 180 FOR I=1 TO IMAX 190 J = INT(RND*IMAX)+1 200 SWAP N(I), N(J) 210 NEXT I 220 PRINT: PRINT "Unsorted list:"; 230 FOR I=1 TO IMAX: PRINT N(I);: NEXT I 240 PRINT: PRINT 250 ' Sorts the list through the Selection Sort Algorithm and shows the results 260 TL! = TIMER 270 PRINT "Sorting"; IMAX; "numbers"; 280 COLOR 7+16: X = POS(0): PRINT"...";: COLOR 7 290 ITP = 0 300 FOR I=1 TO IMAX-1 310 IMINV = I 320 FOR J=I+1 TO IMAX 330 IF N(IMINV)>N(J) THEN IMINV = J 340 NEXT J 350 IF IMINV>I THEN SWAP N(IMINV), N(I): TP! = TP! + 1 360 NEXT I 370 LOCATE ,X: PRINT ". Done!" 380 PRINT: PRINT "Sorted list:"; 390 FOR I=1 TO IMAX: PRINT N(I);: NEXT I 400 ' Final results 410 PRINT: PRINT: PRINT "Numbers sorted:"; IMAX 420 PRINT "Total permutations done:";TP! 430 PRINT "Time lapse:"; TIMER-TL!; "seconds." 440 PRINT 450 PRINT "End of program" 460 END </lang>

C

<lang c>#include <stdio.h>

void selection_sort (int *a, int n) {

   int i, j, m, t;
   for (i = 0; i < n; i++) {
       for (j = i, m = i; j < n; j++) {
           if (a[j] < a[m]) {
               m = j;
           }
       }
       t = a[i];
       a[i] = a[m];
       a[m] = t;
   }

}

int main () {

   int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};
   int n = sizeof a / sizeof a[0];
   int i;
   for (i = 0; i < n; i++)
       printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
   selection_sort(a, n);
   for (i = 0; i < n; i++)
       printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
   return 0;

} </lang>

Output:
4 65 2 -31 0 99 2 83 782 1
-31 0 1 2 2 4 65 83 99 782

C#

This is a generic implementation that works with any type that implements the IComparable interface

<lang csharp>class SelectionSort<T> where T : IComparable {

   public T[] Sort(T[] list) {
       int k;
       T temp;
       for (int i = 0; i < list.Length; i++) {
           k = i;
           for (int j=i + 1; j < list.Length; j++) {
               if (list[j].CompareTo(list[k]) < 0) {
                   k = j;
               }
           }
           temp = list[i];
           list[i] = list[k];
           list[k] = temp;
       }
       return list;
   }

}</lang>

Example of usage: <lang csharp>String[] str = { "this", "is", "a", "test", "of", "generic", "selection", "sort" };

SelectionSort<String> mySort = new SelectionSort<string>();

String[] result = mySort.Sort(str);

for (int i = 0; i < result.Length; i++) {

   Console.WriteLine(result[i]);

}</lang>

Output:
a
generic
is
of
selection
sort
test
this

C++

Uses C++11. Compile with

g++ -std=c++11 selection.cpp

<lang cpp>#include <algorithm>

  1. include <iterator>
  2. include <iostream>

template<typename ForwardIterator> void selection_sort(ForwardIterator begin,

                                                      ForwardIterator end) {
 for(auto i = begin; i != end; ++i) {
   std::iter_swap(i, std::min_element(i, end));
 }

}

int main() {

 int a[] = {100, 2, 56, 200, -52, 3, 99, 33, 177, -199};
 selection_sort(std::begin(a), std::end(a));
 copy(std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, " "));
 std::cout << "\n";

}</lang>

Output:
-199 -52 2 3 33 56 99 100 177 200

Clojure

This is an implementation that mutates a Java arraylist in place.

<lang lisp>(import 'java.util.ArrayList)

(defn arr-swap! [#^ArrayList arr i j]

 (let [t (.get arr i)]
   (doto arr
     (.set i (.get arr j))
     (.set j t))))

(defn sel-sort!

 ([arr] (sel-sort! compare arr))
 ([cmp #^ArrayList arr]
    (let [n (.size arr)]
      (letfn [(move-min!

[start-i] (loop [i start-i] (when (< i n) (when (< (cmp (.get arr i) (.get arr start-i)) 0) (arr-swap! arr start-i i)) (recur (inc i)))))] (doseq [start-i (range (dec n))] (move-min! start-i)) arr))))</lang>

COBOL

<lang COBOL> PERFORM E-SELECTION VARYING WB-IX-1 FROM 1 BY 1

                              UNTIL WB-IX-1 = WC-SIZE.

...

      E-SELECTION SECTION.
      E-000.
          SET WC-LOWEST   TO WB-IX-1.
          ADD 1 WC-LOWEST GIVING WC-START
          PERFORM F-PASS VARYING WB-IX-2 FROM WC-START BY 1
                         UNTIL WB-IX-2 > WC-SIZE.
          IF WB-IX-1 NOT = WC-LOWEST
             MOVE WB-ENTRY(WC-LOWEST) TO WC-TEMP
             MOVE WB-ENTRY(WB-IX-1)   TO WB-ENTRY(WC-LOWEST)
             MOVE WC-TEMP             TO WB-ENTRY(WB-IX-1).
      E-999.
          EXIT.
      F-PASS SECTION.
      F-000.
          IF WB-ENTRY(WB-IX-2) < WB-ENTRY(WC-LOWEST)
             SET WC-LOWEST TO WB-IX-2.
      F-999.
          EXIT.</lang>

Common Lisp

<lang lisp>(defun selection-sort-vector (array predicate)

 (do ((length (length array))
      (i 0 (1+ i)))
     ((eql i length) array)
   (do ((mindex i)
        (min (aref array i))
        (j i (1+ j)))
       ((eql j length)
        (rotatef (aref array i) (aref array mindex)))
     (when (funcall predicate (aref array j) min)
       (setf min (aref array j)
             mindex j)))))

(defun selection-sort-list (list predicate)

 (flet ((min-first (list)
          (do ((before-min nil)
               (min (first list))
               (prev list (rest prev))
               (curr (rest list) (rest curr)))
              ((endp curr)
               (if (null before-min) list
                 (let ((min (cdr before-min)))
                   (rplacd before-min (cdr min))
                   (rplacd min list)
                   min)))
            (when (funcall predicate (first curr) min)
              (setf before-min prev
                    min (first curr))))))
   (let ((result (min-first list)))
     (do ((head result (rest head)))
         ((endp (rest head)) result)
       (rplacd head (min-first (rest head)))))))

(defun selection-sort (sequence predicate)

 (etypecase sequence
   (list (selection-sort-list sequence predicate))
   (vector (selection-sort-vector sequence predicate))))</lang>

Example use:

> (selection-sort (list 8 7 4 3 2 0 9 1 5 6) '<)
(0 1 2 3 4 5 6 7 8 9)

> (selection-sort (vector 8 7 4 3 2 0 9 1 5 6) '>)
#(9 8 7 6 5 4 3 2 1 0)

Crystal

This sorts the array in-place. <lang crystal>def selectionSort(array : Array)

   (0...array.size-1).each do |i|
       nextMinIndex = i
       (i+1...array.size).each do |j|
           if array[j] < array[nextMinIndex]
               nextMinIndex = j
           end
       end    
       if i != nextMinIndex
           array.swap(i, nextMinIndex)
       end
   end

end</lang>

D

The actual function is very short. <lang d>import std.stdio, std.algorithm, std.array, std.traits;

enum AreSortableArrayItems(T) = isMutable!T &&

                               __traits(compiles, T.init < T.init) &&
                               !isNarrowString!(T[]);

void selectionSort(T)(T[] data) if (AreSortableArrayItems!T) {

   foreach (immutable i, ref d; data)
       data.drop(i).minPos[0].swap(d);

} unittest {

   int[] a0;
   a0.selectionSort;
   auto a1 = [1];
   a1.selectionSort;
   assert(a1 == [1]);
   auto a2 = ["a", "b"];
   a2.selectionSort;
   assert(a2 == ["a", "b"]);
   auto a3 = ["b", "a"];
   a3.selectionSort;
   assert(a3 == ["a", "b"]);
   auto a4 = ['a', 'b'];
   static assert(!__traits(compiles, a4.selectionSort));
   dchar[] a5 = ['b', 'a'];
   a5.selectionSort;
   assert(a5 == "ab"d);
   import std.typecons;
   alias Nullable!int N;
   auto a6 = [N(2), N(1)];
   a6.selectionSort; // Not nothrow.
   assert(a6 == [N(1), N(2)]);
   auto a7 = [1.0+0i, 2.0+0i]; // To be deprecated.
   static assert(!__traits(compiles, a7.selectionSort));
   import std.complex;
   auto a8 = [complex(1), complex(2)];
   static assert(!__traits(compiles, a8.selectionSort));
   static struct F {
       int x;
       int opCmp(F f) { // Not pure.
           return x < f.x ? -1 : (x > f.x ? 1 : 0);
       }
   }
   auto a9 = [F(2), F(1)];
   a9.selectionSort;
   assert(a9 == [F(1), F(2)]);

}

void main() {

   auto a = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2];
   a.selectionSort;
   a.writeln;

}</lang>

Output:
[1, 1, 2, 2, 3, 3, 3, 4, 5, 5, 5, 6, 7, 8, 9, 9, 9]

Delphi

Array sort

Dynamic array is a 0-based array of variable length

Static array is an arbitrary-based array of fixed length <lang Delphi>program TestSelectionSort;

{$APPTYPE CONSOLE}

{.$DEFINE DYNARRAY} // remove '.' to compile with dynamic array

type

 TItem = Integer;   // declare ordinal type for array item

{$IFDEF DYNARRAY}

 TArray = array of TItem;          // dynamic array

{$ELSE}

 TArray = array[0..15] of TItem;   // static array

{$ENDIF}

procedure SelectionSort(var A: TArray); var

 Item: TItem;
 I, J, M: Integer;

begin

 for I:= Low(A) to High(A) - 1 do begin
   M:= I;
   for J:= I + 1 to High(A) do
     if A[J] < A[M] then M:= J;
   Item:= A[M];
   A[M]:= A[I];
   A[I]:= Item;
 end;

end;

var

 A: TArray;
 I: Integer;

begin {$IFDEF DYNARRAY}

 SetLength(A, 16);

{$ENDIF}

 for I:= Low(A) to High(A) do
   A[I]:= Random(100);
 for I:= Low(A) to High(A) do
   Write(A[I]:3);
 Writeln;
 SelectionSort(A);
 for I:= Low(A) to High(A) do
   Write(A[I]:3);
 Writeln;
 Readln;

end.</lang>

Output:
  0  3 86 20 27 67 31 16 37 42  8 47  7 84  5 29
  0  3  5  7  8 16 20 27 29 31 37 42 47 67 84 86

String sort

// string is 1-based variable-length array of Char <lang Delphi>procedure SelectionSort(var S: string); var

 Lowest: Char;
 I, J, M, L: Integer;

begin

 L:= Length(S);
 for I:= 1 to L - 1 do begin
   M:= I;
   for J:= I + 1 to L do
     if S[J] < S[M] then M:= J;
   Lowest:= S[M];
   S[M]:= S[I];
   S[I]:= Lowest;
 end;

end;</lang>

// in : S = 'the quick brown fox jumps over the lazy dog'
// out: S = '        abcdeeefghhijklmnoooopqrrsttuuvwxyz'

E

<lang e>def selectionSort := {

 def cswap(c, a, b) {
   def t := c[a]
   c[a]  := c[b]
   c[b]  := t
   println(c)
 }
 
 def indexOfMin(array, first, last) {
   var min := array[first]
   var mini := first
   for i in (first+1)..last {
     if (array[i] < min) {
       min := array[i]
       mini := i
     }
   }
   return mini
 }
 /** Selection sort (in-place). */
 def selectionSort(array) {
   def last := (array.size()-1)
   for i in 0..(last - 1) {
     cswap(array, i, indexOfMin(array, i + 1, last))
   }
 }

}</lang>

EasyLang

<lang>subr sort

 for i = 0 to len data[] - 2
   min_pos = i
   for j = i + 1 to len data[] - 1
     if data[j] < data[min_pos]
       min_pos = j
     .
   .
   swap data[i] data[min_pos]
 .

. data[] = [ 29 4 72 44 55 26 27 77 92 5 ] call sort print data[]</lang>

EchoLisp

List sort

<lang scheme>

recursive version (adapted from Racket)

(lib 'list) ;; list-delete (define (sel-sort xs (x0)) (cond [(null? xs) null] [else (set! x0 (apply min xs)) (cons x0 (sel-sort (list-delete xs x0)))]))

(sel-sort (shuffle (iota 13)))

   → (0 1 2 3 4 5 6 7 8 9 10 11 12)
   
straightforward and more efficient implementation using list-swap!

(define (sel-sort list) (maplist (lambda( L) (first (list-swap! L (first L) (apply min L )))) list))

(sel-sort (shuffle (iota 13)))

   → (0 1 2 3 4 5 6 7 8 9 10 11 12)
   

</lang>

Array sort

<lang scheme>

sort an array in place

(define (sel-sort a (amin) (imin)) (define ilast (1- (vector-length a))) (for [(i ilast)] (set! amin [a (setv! imin i)]) ;; imin := i , amin := a[imin] (for [(j (in-range (1+ i) (1+ ilast)))] (when (< [a j] amin) (set! amin [a (setv! imin j)]))) (vector-swap! a i imin)) a )

(define a #(9 8 2 6 3 5 4)) (sel-sort a)

   → #( 2 3 4 5 6 8 9)		

</lang>

Eiffel

<lang Eiffel> class SELECTION_SORT [G -> COMPARABLE]

feature {NONE}

index_of_min (ar: ARRAY [G]; lower: INTEGER): INTEGER --Index of smallest element in 'ar' in the range of lower and the max index. require lower_positiv: lower >= 1 lower_in_range: lower <= ar.count ar_not_void: ar /= Void local i: INTEGER min: G do from i := lower min := ar.item (i) Result := i until i + 1 > ar.count loop if ar.item (i + 1) < min then min := ar.item (i + 1) Result := i + 1 end i := i + 1 end ensure result_is_set: Result /= Void end

sort (ar: ARRAY [G]): ARRAY [G] -- sort array ar with selectionsort require ar_not_void: ar /= Void local min_index: INTEGER ith: G do create Result.make_empty Result.deep_copy (ar) across Result as ic loop min_index := index_of_min (Result, ic.cursor_index) ith := Result [ic.cursor_index] Result [ic.cursor_index] := Result [min_index] Result [min_index] := ith end ensure Result_is_set: Result /= Void Result_sorted: is_sorted (Result) = True end

is_sorted (ar: ARRAY [G]): BOOLEAN --- Is 'ar' sorted in ascending order? require ar_not_empty: ar.is_empty = False local i: INTEGER do Result := True from i := ar.lower until i = ar.upper loop if ar [i] > ar [i + 1] then Result := False end i := i + 1 end end

feature

selectionsort (ar: ARRAY [G]): ARRAY [G] do Result := sort (ar) end

end </lang> Test: <lang eiffel> class APPLICATION

create make

feature

make do test := <<1, 27, 32, 99, 1, -7, 3, 5, 7>> io.put_string ("Unsorted: ") across test as ic loop io.put_string (ic.item.out + " ") end create selectionsort io.put_string ("%NSorted: ") test := selectionsort.selectionsort (test) across test as ar loop io.put_string (ar.item.out + " ") end end

test: ARRAY [INTEGER]

selectionsort: SELECTION_SORT [INTEGER]

end </lang>

Output:
Unsorted: 1 27 32 99 1 -7 3 5 7
Sorted: -7 1 1 3 5 7 27 32 99

Elena

ELENA 5.0 : <lang elena>import extensions; import system'routines;

extension op {

   selectionSort()
   {
       var copy := self.clone();

       for(int i := 0, i < copy.Length, i += 1)
       {
           int k := i;
           for(int j := i + 1, j < copy.Length, j += 1)
           {
               if (copy[j] < copy[k])
               {
                   k := j
               }
           };
           copy.exchange(i,k)
       };        

       ^ copy
   }

}

public program() {

   var list := new string[]{"this", "is", "a", "test", "of", "generic", "selection", "sort"};

   console.printLine("before:",list.asEnumerable());
   console.printLine("after:",list.selectionSort().asEnumerable())

}</lang>

Output:
before:this,is,a,test,of,generic,selection,sort
after:a,generic,is,of,selection,sort,test,this

Elixir

<lang elixir>defmodule Sort do

 def selection_sort(list) when is_list(list), do: selection_sort(list, [])
 
 defp selection_sort([], sorted), do: sorted
 defp selection_sort(list, sorted) do
   max = Enum.max(list)
   selection_sort(List.delete(list, max), [max | sorted])
 end

end</lang>

Example:

iex(10)> Sort.selection_sort([5,3,9,4,1,6,8,2,7])
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Erlang

<lang Erlang> -module(solution). -import(lists,[delete/2,max/1]). -compile(export_all). selection_sort([],Sort)-> Sort; selection_sort(Ar,Sort)-> M=max(Ar), Ad=delete(M,Ar), selection_sort(Ad,[M|Sort]). print_array([])->ok; print_array([H|T])-> io:format("~p~n",[H]), print_array(T).

main()-> Ans=selection_sort([1,5,7,8,4,10],[]), print_array(Ans). </lang>

Euphoria

<lang euphoria>function selection_sort(sequence s)

   object tmp
   integer m
   for i = 1 to length(s) do
       m = i
       for j = i+1 to length(s) do
           if compare(s[j],s[m]) < 0 then
               m = j
           end if
       end for
       tmp = s[i]
       s[i] = s[m]
       s[m] = tmp
   end for
   return s

end function

include misc.e constant s = {4, 15, "delta", 2, -31, 0, "alfa", 19, "gamma", 2, 13, "beta", 782, 1}

puts(1,"Before: ") pretty_print(1,s,{2}) puts(1,"\nAfter: ") pretty_print(1,selection_sort(s),{2})</lang>

Output:
Before: {
  4,
  15,
  "delta",
  2,
  -31,
  0,
  "alfa",
  19,
  "gamma",
  2,
  13,
  "beta",
  782,
  1
}
After: {
  -31,
  0,
  1,
  2,
  2,
  4,
  13,
  15,
  19,
  782,
  "alfa",
  "beta",
  "delta",
  "gamma"
}

F#

<lang fsharp> let rec ssort = function

   [] -> []
   | x::xs -> 
       let min, rest =
           List.fold (fun (min,acc) x ->
                            if h<min then (h, min::acc)
                            else (min, h::acc))
             (x, []) xs
       in min::ssort rest

</lang>

Factor

<lang factor>USING: kernel math sequences sequences.extras ;

select ( m n seq -- )
   [ dup ] 2dip [ <slice> [ ] infimum-by* drop over + ]
   [ exchange ] bi ;
selection-sort! ( seq -- seq' )
   [ ] [ length dup ] [ ] tri [ select ] 2curry each-integer ;</lang>

Example use <lang factor>IN: scratchpad { 5 -6 3 9 -2 4 -1 -6 5 -5 } selection-sort!

--- Data stack: { -6 -6 -5 -2 -1 3 4 5 5 9 }</lang>

Forth

<lang forth>defer less? ' < is less?

least ( start end -- least )
 over cell+ do
   i @ over @ less? if drop i then
 cell +loop ;
selection ( array len -- )
 cells over + tuck ( end start end )
 cell- swap do   ( end )
   i over least ( end least )
   i @ over @ i ! swap !
 cell +loop drop ;

create array 8 , 1 , 4 , 2 , 10 , 3 , 7 , 9 , 6 , 5 ,

array 10 selection array 10 cells dump</lang>

Fortran

Works with: Fortran version 95 and later

<lang fortran>PROGRAM SELECTION

 IMPLICIT NONE
 INTEGER :: intArray(10) = (/ 4, 9, 3, -2, 0, 7, -5, 1, 6, 8 /)

 WRITE(*,"(A,10I5)") "Unsorted array:", intArray
 CALL Selection_sort(intArray)
 WRITE(*,"(A,10I5)") "Sorted array  :", intArray
  

CONTAINS

 SUBROUTINE Selection_sort(a)
   INTEGER, INTENT(IN OUT) :: a(:)
   INTEGER :: i, minIndex, temp
   DO i = 1, SIZE(a)-1
      minIndex = MINLOC(a(i:), 1) + i - 1
      IF (a(i) > a(minIndex)) THEN
         temp = a(i)
         a(i) = a(minIndex)
         a(minIndex) = temp
      END IF
   END DO
 END SUBROUTINE Selection_sort

END PROGRAM SELECTION</lang>

Output:
Unsorted array:    4    9    3   -2    0    7   -5    1    6    8
Sorted array  :   -5   -2    0    1    3    4    6    7    8    9

FreeBASIC

<lang freebasic>' version 03-12-2016 ' compile with: fbc -s console ' for boundry checks on array's compile with: fbc -s console -exx

Sub selectionsort(arr() As Long)

   ' sort from lower bound to the highter bound
   ' array's can have subscript range from -2147483648 to +2147483647
   Dim As Long i, j, x
   Dim As Long lb = LBound(arr)
   Dim As Long ub = UBound(arr)
   For i = lb To ub -1
       x = i
       For j = i +1 To ub
           If arr(j) < arr(x) Then x = j
       Next
       If x <> i Then
           Swap arr(i), arr(x)
       End If
   Next

End Sub

' ------=< MAIN >=------

Dim As Long i, array(-7 To 7) Dim As Long a = LBound(array), b = UBound(array)

Randomize Timer For i = a To b : array(i) = i  : Next For i = a To b ' little shuffle

   Swap array(i), array(Int(Rnd * (b - a +1)) + a)

Next

Print "unsort "; For i = a To b : Print Using "####"; array(i); : Next : Print selectionsort(array()) ' sort the array Print " sort "; For i = a To b : Print Using "####"; array(i); : Next : Print

' empty keyboard buffer While InKey <> "" : Wend Print : Print "hit any key to end program" Sleep End</lang>

Output:
unsort    1  -7  -5  -4   6   5  -3   4   2   0   3  -6  -2   7  -1
  sort   -7  -6  -5  -4  -3  -2  -1   0   1   2   3   4   5   6   7

Gambas

<lang gambas> siLow As Short = -99 'Set the lowest value number to create siHigh As Short = 99 'Set the highest value number to create siQty As Short = 20 'Set the quantity of numbers to create

Public Sub Main() Dim siToSort As Short[] = CreateNumbersToSort() Dim siPos, siLow, siChar, siCount As Short

PrintOut("To sort: ", siToSort)

For siCount = 0 To siToSort.Max

 siChar = siCount
 For siPos = siCount + 1 To siToSort.Max
   If siToSort[siChar] > siToSort[siPos] Then siChar = siPos
 Next
 siLow = siToSort[siChar]
 siToSort.Delete(siChar, 1)
 siToSort.Add(siLow, siCount)

Next

PrintOut(" Sorted: ", siToSort)

End '--------------------------------------------------------- Public Sub PrintOut(sText As String, siToSort As String[]) Dim siCount As Short

Print sText;

For siCount = 0 To siToSort.Max

 Print siToSort[siCount];
 If siCount <> siToSort.max Then Print ", ";

Next

Print

End '--------------------------------------------------------- Public Sub CreateNumbersToSort() As Short[] Dim siCount As Short Dim siList As New Short[]

For siCount = 0 To siQty

 siList.Add(Rand(siLow, siHigh))

Next

Return siList

End</lang>

Output:

To sort: -11, -64, -20, -84, 94, -60, -82, -82, 37, -30, -75, 73, 19, -97, 81, -26, 55, 8, -15, -31, 36
 Sorted: -97, -84, -82, -82, -75, -64, -60, -31, -30, -26, -20, -15, -11, 8, 19, 36, 37, 55, 73, 81, 94

GAP

<lang gap>SelectionSort := function(v)

  local i, j, k, n, m;
  n := Size(v);
  for i in [1 .. n] do
     k := i;
     m := v[i];
     for j in [i + 1 .. n] do
        if v[j] < m then
           k := j;
           m := v[j];
        fi;
     od;
     v[k] := v[i];
     v[i] := m;
  od;

end;

v := List([1 .. 100], n -> Random([1 .. 100])); SelectionSort(v); v;</lang>

Go

<lang go>package main

import "fmt"

var a = []int{170, 45, 75, -90, -802, 24, 2, 66}

func main() {

   fmt.Println("before:", a)
   selectionSort(a)
   fmt.Println("after: ", a)

}

func selectionSort(a []int) {

   last := len(a) - 1
   for i := 0; i < last; i++ {
       aMin := a[i]
       iMin := i
       for j := i + 1; j < len(a); j++ {
           if a[j] < aMin {
               aMin = a[j]
               iMin = j
           }
       }
       a[i], a[iMin] = aMin, a[i]
   }

}</lang>

More generic version that sorts anything that implements sort.Interface: <lang go>package main

import (

 "sort"
 "fmt"

)

var a = []int{170, 45, 75, -90, -802, 24, 2, 66}

func main() {

   fmt.Println("before:", a)
   selectionSort(sort.IntSlice(a))
   fmt.Println("after: ", a)

}

func selectionSort(a sort.Interface) {

   last := a.Len() - 1
   for i := 0; i < last; i++ {
       iMin := i
       for j := i + 1; j < a.Len(); j++ {
           if a.Less(j, iMin) {
               iMin = j
           }
       }
       a.Swap(i, iMin)
   }

}</lang>

Haskell

<lang haskell>import Data.List (delete)

selSort :: (Ord a) => [a] -> [a] selSort [] = [] selSort xs = selSort (delete x xs) ++ [x]

 where x = maximum xs</lang>

Haxe

<lang haxe>class SelectionSort {

 @:generic
 public static function sort<T>(arr:Array<T>) {
   var len = arr.length;
   for (index in 0...len) {
     var minIndex = index;
     for (remainingIndex in (index+1)...len) {
       if (Reflect.compare(arr[minIndex], arr[remainingIndex]) > 0)
         minIndex = remainingIndex;
     }
     if (index != minIndex) {
       var temp = arr[index];
       arr[index] = arr[minIndex];
       arr[minIndex] = temp;
     }
   }
 }

}

class Main {

 static function main() {
   var integerArray   = [1, 10, 2, 5, -1, 5, -19, 4, 23, 0];
   var floatArray = [1.0, -3.2, 5.2, 10.8, -5.7, 7.3, 
                     3.5, 0.0, -4.1, -9.5];
   var stringArray = ['We', 'hold', 'these', 'truths', 'to', 
                      'be', 'self-evident', 'that', 'all', 
                      'men', 'are', 'created', 'equal'];
   Sys.println('Unsorted Integers:' + integerArray);
   SelectionSort.sort(integerArray);
   Sys.println('Sorted Integers:  ' + integerArray);
   Sys.println('Unsorted Floats:  ' + floatArray);
   SelectionSort.sort(floatArray);
   Sys.println('Sorted Floats:    ' + floatArray);
   Sys.println('Unsorted Strings: ' + stringArray);
   SelectionSort.sort(stringArray);
   Sys.println('Sorted Strings:   ' + stringArray);
 }

}</lang>

Output:
Unsorted Integers: [1,10,2,5,-1,5,-19,4,23,0]
Sorted Integers:   [-19,-1,0,1,2,4,5,5,10,23]
Unsorted Floats:   [1,-3.2,5.2,10.8,-5.7,7.3,3.5,0,-4.1,-9.5]
Sorted Floats:     [-9.5,-5.7,-4.1,-3.2,0,1,3.5,5.2,7.3,10.8]
Unsorted Strings:  [We,hold,these,truths,to,be,self-evident,that,all,men,are,created,equal]
Sorted Strings:    [We,all,are,be,created,equal,hold,men,self-evident,that,these,to,truths]

Icon and Unicon

<lang Icon>procedure main() #: demonstrate various ways to sort a list and string

  demosort(selectionsort,[3, 14, 1, 5, 9, 2, 6, 3],"qwerty")

end


procedure selectionsort(X,op) #: return sorted list ascending(or descending) local i,m

  op := sortop(op,X)                                   # select how and what we sort
  every i := 1 to *X-1 do {
     m := i 
     every j := i + 1 to *X do
        if op(X[j],X[m]) then m := j                   # find X that belongs @i low (or high)
     X[m ~= i] :=: X[m]
     }
  return X

end</lang>

Note: This example relies on the supporting procedures 'sortop', and 'demosort' in Bubble Sort. The full demosort exercises the named sort of a list with op = "numeric", "string", ">>" (lexically gt, descending),">" (numerically gt, descending), a custom comparator, and also a string.

Output:

Abbreviated sample

Sorting Demo using procedure selectionsort
  on list : [ 3 14 1 5 9 2 6 3 ]
    with op = &null:         [ 1 2 3 3 5 6 9 14 ]   (0 ms)
  ...
  on string : "qwerty"
    with op = &null:         "eqrtwy"   (0 ms)

Io

<lang io>List do (

   selectionSortInPlace := method(
       size repeat(idx,
           swapIndices(idx, indexOf(slice(idx, size) min))
       )
   )

)

l := list(-1, 4, 2, -9) l selectionSortInPlace println # ==> list(-9, -1, 2, 4)</lang>

IS-BASIC

<lang IS-BASIC>100 PROGRAM "SelecSrt.bas" 110 RANDOMIZE 120 NUMERIC ARRAY(-5 TO 14) 130 CALL INIT(ARRAY) 140 CALL WRITE(ARRAY) 150 CALL SELECTIONSORT(ARRAY) 160 CALL WRITE(ARRAY) 170 DEF INIT(REF A) 180 FOR I=LBOUND(A) TO UBOUND(A) 190 LET A(I)=RND(98)+1 200 NEXT 210 END DEF 220 DEF WRITE(REF A) 230 FOR I=LBOUND(A) TO UBOUND(A) 240 PRINT A(I); 250 NEXT 260 PRINT 270 END DEF 280 DEF SELECTIONSORT(REF A) 290 FOR I=LBOUND(A) TO UBOUND(A)-1 300 LET MN=A(I):LET INDEX=I 310 FOR J=I+1 TO UBOUND(A) 320 IF MN>A(J) THEN LET MN=A(J):LET INDEX=J 330 NEXT 340 LET A(INDEX)=A(I):LET A(I)=MN 350 NEXT 360 END DEF</lang>

J

Generally, this task should be accomplished in J using /:~. Here we take an approach that's more comparable with the other examples on this page.

Create the following script and load it to a J session. <lang j>selectionSort=: verb define

 data=. y
 for_xyz. y do.
   temp=. xyz_index }. data
   nvidx=. xyz_index + temp i. <./ temp
   data=. ((xyz_index, nvidx) { data) (nvidx, xyz_index) } data
 end.
 data

)</lang>

In an email discussion, Roger_Hui presented the following tacit code: <lang j>ix=: C.~ <@~.@(0, (i. <./)) ss1=: ({. , $:@}.)@ix^:(*@#)</lang>

To validate: <lang j> [data=. 6 15 19 12 14 19 0 17 0 14 6 15 19 12 14 19 0 17 0 14

  selectionSort data

0 0 6 12 14 14 15 17 19 19

  ss1 data

0 0 6 12 14 14 15 17 19 19</lang>

Java

This algorithm sorts in place. The call sort(array) will rearrange the array and not create a new one. <lang java>public static void sort(int[] nums){ for(int currentPlace = 0;currentPlace<nums.length-1;currentPlace++){ int smallest = Integer.MAX_VALUE; int smallestAt = currentPlace+1; for(int check = currentPlace; check<nums.length;check++){ if(nums[check]<smallest){ smallestAt = check; smallest = nums[check]; } } int temp = nums[currentPlace]; nums[currentPlace] = nums[smallestAt]; nums[smallestAt] = temp; } }</lang>

JavaScript

This algorithm sorts array of numbers. <lang javascript>function selectionSort(nums) {

 var len = nums.length;
 for(var i = 0; i < len; i++) {
   var minAt = i;
   for(var j = i + 1; j < len; j++) {
     if(nums[j] < nums[minAt])
       minAt = j;
   }
   if(minAt != i) {
     var temp = nums[i];
     nums[i] = nums[minAt];
     nums[minAt] = temp;
   }
 }
 return nums;

}</lang>

jq

The following implementation does not impose any restrictions on the types of entities that may appear in the array to be sorted. That is, the array may include any collection of JSON entities.

The definition also illustrates the use of an inner function (swap), and the use of jq's reduction operator, reduce.<lang jq># Sort any array def selection_sort:

 def swap(i;j): if i == j then . else .[i] as $tmp | .[i] = .[j] | .[j] = $tmp end;
 length as $length
 | reduce range(0; $length) as $currentPlace
     # state: $array
     ( .;
       . as $array
       | (reduce range( $currentPlace; $length) as $check
           # state: [ smallestAt, smallest] except initially [null]
           ( [$currentPlace+1] ;
              if length == 1 or $array[$check] < .[1]
              then [$check, $array[$check] ]
              else .
              end
            )) as $ans
         | swap( $currentPlace; $ans[0] )
         ) ;</lang>Example:<lang jq>

[1, 3.3, null, 2, null, [1,{"a":1 }] ] | selection_sort </lang>

Output:
[
  null,
  null,
  1,
  2,
  3.3,
  [
    1,
    {
      "a": 1
    }
  ]
]

Julia

Works with: Julia version 0.6

<lang julia>function selectionsort!(arr::Vector{<:Real})

   len = length(arr)
   if len < 2 return arr end
   for i in 1:len-1
       lmin, j = findmin(arr[i+1:end])
       if lmin < arr[i]
           arr[i+j] = arr[i]
           arr[i] = lmin
       end
   end
   return arr

end

v = rand(-10:10, 10) println("# unordered: $v\n -> ordered: ", selectionsort!(v))</lang>

Output:
# unordered: [2, -10, 0, -10, -9, -3, -3, 7, 8, -3]
 -> ordered: [-10, -10, -9, -3, -3, -3, 0, 2, 7, 8]

Kotlin

Translation of: C#

<lang scala>fun <T : Comparable<T>> Array<T>.selection_sort() {

   for (i in 0..size - 2) {
       var k = i
       for (j in i + 1..size - 1)
           if (this[j] < this[k])
               k = j
       if (k != i) {
           val tmp = this[i]
           this[i] = this[k]
           this[k] = tmp
       }
   }

}

fun main(args: Array<String>) {

   val i = arrayOf(4, 9, 3, -2, 0, 7, -5, 1, 6, 8)
   i.selection_sort()
   println(i.joinToString())
   val s = Array(i.size, { -i[it].toShort() })
   s.selection_sort()
   println(s.joinToString())
   val c = arrayOf('z', 'h', 'd', 'c', 'a')
   c.selection_sort()
   println(c.joinToString())

}</lang>

Output:
-5, -2, 0, 1, 3, 4, 6, 7, 8, 9
-9, -8, -7, -6, -4, -3, -1, 0, 2, 5
a, c, d, h, z

Liberty BASIC

<lang lb> itemCount = 20

   dim A(itemCount)
   for i = 1 to itemCount
       A(i) = int(rnd(1) * 100)
   next i
   print "Before Sort"
   gosub [printArray]

'--- Selection sort algorithm

   for i = 1 to itemCount-1
       jMin = i
       for j = i+1 to itemCount
           if A(j) < A(jMin) then jMin = j
       next
       tmp = A(i)
       A(i) = A(jMin)
       A(jMin) = tmp
   next

'--- end of (Selection sort algorithm)

   print "After Sort"
   gosub [printArray]

end

[printArray]

   for i = 1 to itemCount
       print using("###", A(i));
   next i
   print

return </lang>

LSE

<lang LSE> (*

    • Tri par Sélection
    • (LSE2000)
  • )

PROCEDURE &Test(TABLEAU DE ENTIER pDonnees[], ENTIER pTaille) LOCAL pTaille

   ENTIER i, j, minimum, tmp
   POUR  i <- 0 JUSQUA pTaille-1 FAIRE
       minimum <- i
       POUR j <- i+1 JUSQUA pTaille FAIRE
           SI pDonnees[j] < pDonnees[minimum] ALORS
               minimum <- j
           FIN SI
       BOUCLER
       SI i # min ALORS
           tmp <- pDonnees[i]
           pDonnees[i] <- pDonnees[minimum]
           pDonnees[minimum] <- tmp
       FIN SI
   BOUCLER

FIN PROCEDURE </lang>

Lua

<lang lua>function SelectionSort( f )

   for k = 1, #f-1 do    
       local idx = k    
       for i = k+1, #f do
           if f[i] < f[idx] then 
               idx = i
           end    
       end
       f[k], f[idx] = f[idx], f[k]
   end

end


f = { 15, -3, 0, -1, 5, 4, 5, 20, -8 }

SelectionSort( f )

for i in next, f do

   print( f[i] )

end</lang>

Maple

<lang Maple>arr:= Array([17,3,72,0,36,2,3,8,40,0]): len := numelems(arr): for i to len-1 do j_min := i: for j from i+1 to len do if arr[j] < arr[j_min] then j_min := j: end if: end do: if (not j_min = i) then temp := arr[i]: arr[i] := arr[j_min]: arr[j_min] := temp: end if: end do: arr;</lang>

Output:
[0,0,2,3,3,8,17,36,40,72]

Mathematica

Procedural solution with custom min function:

<lang Mathematica>SelectSort[x_List] := Module[{n = 1, temp, xi = x, j},

 While[n <= Length@x,
  temp = xin;
  For[j = n, j <= Length@x, j++,
   If[xij < temp, temp = xij];
   ];
  xin ;; = {temp}~Join~
    Delete[xin ;;, First@Position[xin ;;, temp] ];
  n++;
  ];
 xi
 ]</lang>

Recursive solution using a pre-existing Min[] function:

<lang Mathematica>SelectSort2[x_List]:= Flatten[{Min@x, If[Length@x > 1, SelectSort2@Drop[x, First@Position[x, Min@x]], {}] }];</lang>

Validate by testing the ordering of a random number of randomly-sized random lists:

<lang Mathematica>{And @@ Table[l = RandomInteger[150, RandomInteger[1000]];

  Through[And[Length@# == Length@SelectSort@# &, OrderedQ@SelectSort@# &]@l],
  {RandomInteger[150]}],
Block[{$RecursionLimit = Infinity},
 And @@ Table[l = RandomInteger[150, RandomInteger[1000]];
   Through[And[Length@# == Length@SelectSort2@# &, OrderedQ@SelectSort2@# &]@l],
   {RandomInteger[150]}]
 ]}</lang>

Validation Result:

{True, True}

MATLAB / Octave

<lang MATLAB>function list = selectionSort(list)

   listSize = numel(list);
   
   for i = (1:listSize-1)
       minElem = list(i);
       minIndex = i;
       
       %This for loop can be vectorized, but there will be no significant
       %increase in sorting efficiency.
       for j = (i:listSize)    
           if list(j) <= minElem
               minElem = list(j);
               minIndex = j;
           end                              
       end
       
       if i ~= minIndex
           list([minIndex i]) = list([i minIndex]); %Swap
       end
       
   end %for

end %selectionSort</lang>

Sample Usage: <lang MATLAB>>> selectionSort([4 3 1 5 6 2])

ans =

    1     2     3     4     5     6</lang>

Maxima

<lang maxima>selection_sort(v) := block([k, m, n], n: length(v), for i: 1 thru n do (

  k: i,
  m: v[i],
  for j: i + 1 thru n do
     if v[j] < m then (k: j, m: v[j]),
  v[k]: v[i],
  v[i]: m

))$

v: makelist(random(199) - 99, i, 1, 10); /* [52, -85, 41, -70, -59, 88, 19, 80, 90, 44] */ selection_sort(v)$ v; /* [-85, -70, -59, 19, 41, 44, 52, 80, 88, 90] */</lang>

MAXScript

<lang maxscript>fn selectionSort arr = (

   local min = undefined
   for i in 1 to arr.count do
   (
       min = i
       for j in i+1 to arr.count do
       (
           if arr[j] < arr[min] then
           (
               min = j
           )
       )
       swap arr[i] arr[min]
   )
   arr

)

data = selectionSort #(4, 9, 3, -2, 0, 7, -5, 1, 6, 8) print data</lang>

N/t/roff

<lang N/t/roff>.de end .. .de array . nr \\$1.c 0 1 . de \\$1.push end . nr \\$1..\\\\n+[\\$1.c] \\\\$1 . end . de \\$1.pushln end . if \\\\n(.$>0 .\\$1.push \\\\$1 . if \\\\n(.$>1 \{ \ . shift . \\$1.pushln \\\\$@ . \} . end . de \\$1.dump end . nr i 0 1 . while \\\\n+i<=\\\\n[\\$1.c] .tm \\\\n[\\$1..\\\\ni] . rr i . end . de \\$1.swap end . if (\\\\$1<=\\\\n[\\$1.c])&(\\\\$2<=\\\\n[\\$1.c]) \{ \ . nr b \\\\n[\\$1..\\\\$1] . nr \\$1..\\\\$1 \\\\n[\\$1..\\\\$2] . nr \\$1..\\\\$2 \\\\nb . rr b . \} . end .. .array myArray .myArray.pushln 14 62 483 21 12 11 0 589 212 10 5 4 95 4 2 2 12 0 0 .de sort . nr i 0 1 . while \\n+i<=\\n[\\$1.c] \{ \ . nr j \\ni 1 . nr st \\nj . while \\n+j<=\\n[\\$1.c] \{ \ . if \\n[\\$1..\\nj]<\\n[\\$1..\\n(st] .nr st \\nj . \} . if !\\n(st=\\ni .\\$1.swap \\ni \\n(st . \} .. .sort myArray .myArray.dump</lang>

Output

<lang>0 0 0 2 2 4 4 5 10 11 12 12 14 21 62 95 212 483 589</lang>

Nanoquery

Translation of: Java

<lang Nanoquery>import math

def sort(nums) global math for currentPlace in range(0, len(nums) - 2) smallest = math.maxint smallestAt = currentPlace + 1 for check in range(currentPlace, len(nums) - 1) if nums[check] < smallest smallestAt = check smallest = nums[check] end end temp = nums[currentPlace] nums[currentPlace] = nums[smallestAt] nums[smallestAt] = temp end return nums end</lang>

Nemerle

Translation of: C#

<lang Nemerle>using System; using System.Console;

module Selection {

   public static Sort[T](this a : array[T]) : void
     where T : IComparable
   {
       mutable k = 0;
       def lastindex = a.Length - 1;
       
       foreach (i in [0 .. lastindex])
       {
           k = i;
           foreach (j in [i .. lastindex])
               when (a[j].CompareTo(a[k]) < 0) k = j;
           a[i] <-> a[k];
       }
   }
   
   Main() : void
   {
       def arr = array[6, 2, 8, 3, 9, 4, 7, 3, 9, 1];
       arr.Sort();
       foreach (i in arr) Write($"$i  ");
   }

}</lang>

NetRexx

<lang NetRexx>/* 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 -
 , selectionSort(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 selectionSort(a = String[]) public constant binary returns String[]

 rl = String[a.length]
 al = List selectionSort(Arrays.asList(a))
 al.toArray(rl)
 return rl

method selectionSort(a = List) public constant binary returns ArrayList

 ra = ArrayList(a)
 n  = ra.size
 iPos = int
 iMin = int
 loop iPos = 0 to n - 1
   iMin = iPos
   loop i_ = iPos + 1 to n - 1
     if (Comparable ra.get(i_)).compareTo(Comparable ra.get(iMin)) < 0 then do
       iMin = i_
       end
     end i_
   if iMin \= iPos then do
     swap = ra.get(iPos)
     ra.set(iPos, ra.get(iMin))
     ra.set(iMin, swap)
     end
   end iPos
 return ra

</lang>

Output:
UK  London
US  New York
US  Boston
US  Washington
UK  Washington
US  Birmingham
UK  Birmingham
UK  Boston

UK  Birmingham
UK  Boston
UK  London
UK  Washington
US  Birmingham
US  Boston
US  New York
US  Washington

Nim

<lang nim>proc selectionSort[T](a: var openarray[T]) =

 let n = a.len
 for i in 0 ..< n:
   var m = i
   for j in i ..< n:
     if a[j] < a[m]:
       m = j
   swap a[i], a[m]

var a = @[4, 65, 2, -31, 0, 99, 2, 83, 782] selectionSort a echo a</lang>

Output:
@[-31, 0, 2, 2, 4, 65, 83, 99, 782]

OCaml

<lang ocaml>let rec selection_sort = function

   [] -> []
 | first::lst ->
     let rec select_r small output = function
         [] -> small :: selection_sort output
       | x::xs when x < small -> select_r x (small::output) xs
       | x::xs                -> select_r small (x::output) xs
     in
     select_r first [] lst</lang>

Oforth

<lang Oforth>: selectSort(l) | b j i k s |

  l size ->s
  l asListBuffer ->b
  s loop: i [
     i dup ->k b at 
     i 1 + s for: j [ b at(j) 2dup <= ifTrue: [ drop ] else: [ nip j ->k ] ]
     k i b at b put i swap b put
     ]
  b dup freeze ;</lang>

ooRexx

<lang oorexx>/*REXX ****************************************************************

  • program sorts an array using the selection-sort method.
  • derived from REXX solution
  • Note that ooRexx can process Elements of the stem argument (Use Arg)
  • 06.10.2010 Walter Pachl
                                                                                                                                            • /

call generate /*generate the array elements. */ call show 'before sort' /*show the before array elements,*/ call selectionSort x. /*invoke the selection sort. */ call show 'after sort' /*show the after array elements.*/ exit /*stick a fork in it, we're done.*/

selectionSort: Procedure

 Use Arg s.                        /* gain access to the argument   */
 do j=1 To s.0-1
   t=s.j;
   p=j;
   do k=j+1 to s.0
     if s.k<t then do;
       t=s.k;
       p=k;
       end
     end
   if p=j then
     iterate
   t=s.j;
   s.j=s.p;
   s.p=t
   end
 return

show:

 Parse Arg heading
 Say heading
 Do i=1 To x.0
   Say i'  'x.i
   End
 say copies('-',79)
 Return

return

generate:

 x.1='---The seven hills of Rome:---'
 x.2='=============================='
 x.3='Caelian'
 x.4='Palatine'
 x.5='Capitoline'
 x.6='Virminal'
 x.7='Esquiline'
 x.8='Quirinal'
 x.9='Aventine'
 x.0=9
 return</lang>

Oz

Although lists are much more used in Oz than arrays, this algorithm seems more natural for arrays. <lang oz>declare

 proc {SelectionSort Arr}
    proc {Swap K L}
       Arr.K := (Arr.L := Arr.K)
    end
    Low = {Array.low Arr}
    High = {Array.high Arr}
 in
    %% for every index I of the array
    for I in Low..High do

%% find the index of the minimum element %% with an index >= I Min = {NewCell Arr.I}

       MinIndex = {NewCell I}
    in
       for J in I..High do
 	 if Arr.J < @Min then

Min := Arr.J MinIndex := J

 	 end

end %% and put that minimum element to the left {Swap @MinIndex I}

    end
 end
 
 A = {Tuple.toArray unit(3 1 4 1 5 9 2 6 5)}

in

 {SelectionSort A}
 {Show {Array.toRecord unit A}}</lang>

PARI/GP

<lang parigp>selectionSort(v)={

 for(i=1,#v-1,
   my(mn=i,t);
   for(j=i+1,#v,
     if(v[j]<v[mn],mn=j)
   );
   t=v[mn];
   v[mn]=v[i];
   v[i]=t
 );
 v

};</lang>

Pascal

See Delphi

Perl

Translation of: Tcl

<lang perl>sub selection_sort

 {my @a = @_;
  foreach my $i (0 .. $#a - 1)
     {my $min = $i + 1;
      $a[$_] < $a[$min] and $min = $_ foreach $min .. $#a;
      $a[$i] > $a[$min] and @a[$i, $min] = @a[$min, $i];}
  return @a;}</lang>

Phix

with javascript_semantics

function selection_sort(sequence s)
    for i=1 to length(s) do
        integer m = i
        object si = s[i],
               sm = s[m]
        for j=i+1 to length(s) do
            object sj = s[j]
            if sj<sm then
                {sm,m} = {sj,j}
            end if
        end for
        if sm<si then
            s[i] = sm
            s[m] = si
        end if
    end for
    return s
end function

?selection_sort(shuffle(tagset(10)))
Output:
{1,2,3,4,5,6,7,8,9,10}

PHP

Iterative: <lang php>function selection_sort(&$arr) {

   $n = count($arr);
   for($i = 0; $i < count($arr); $i++) {
       $min = $i;
       for($j = $i + 1; $j < $n; $j++){
           if($arr[$j] < $arr[$min]){
               $min = $j;
           }
       }
       list($arr[$i],$arr[$min]) = array($arr[$min],$arr[$i]);
   }

}</lang> Recursive: <lang php>function selectionsort($arr,$result=array()){

   if(count($arr) == 0){
       return $result;
   }
   $nresult = $result;
   $nresult[] = min($arr);
   unset($arr[array_search(min($arr),$arr)]);
   return selectionsort($arr,$nresult);	

}</lang>

PicoLisp

<lang PicoLisp>(de selectionSort (Lst)

  (map
     '((L) (and (cdr L) (xchg L (member (apply min @) L))))
     Lst )
  Lst )</lang>

PL/I

<lang PL/I> Selection: procedure options (main); /* 2 November 2013 */

  declare a(10) fixed binary initial (
     5, 7, 3, 98, 4, -3, 25, 20, 60, 17);
  put edit (trim(a)) (a, x(1));
  call Selection_Sort (a);
  put skip edit (trim(a)) (a, x(1));

Selection_sort: procedure (a);

  declare a(*) fixed binary;
  declare t fixed binary;
  declare n fixed binary;
  declare (i, j, k) fixed binary;
  n = hbound(a,1);
  do j = 1 to n;
     k = j; t = a(j);
     do i = j+1 to n;
        if t > a(i) then do; t = a(i); k = i; end;
     end;
     a(k) = a(j); a(j) = t;
  end;

end Selection_Sort;

end Selection; </lang> Results:

5 7 3 98 4 -3 25 20 60 17
-3 3 4 5 7 17 20 25 60 98

PowerShell

<lang PowerShell>Function SelectionSort( [Array] $data ) { $datal=$data.length-1 0..( $datal - 1 ) | ForEach-Object { $min = $data[ $_ ] $mini = $_ ( $_ + 1 )..$datal | ForEach-Object { if( $data[ $_ ] -lt $min ) { $min = $data[ $_ ] $mini = $_ } } $temp = $data[ $_ ] $data[ $_ ] = $min $data[ $mini ] = $temp } $data }

$l = 100; SelectionSort( ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( 0, $l - 1 ) } ) )</lang>

Prolog

Works with SWI-Prolog 6.3.11 (needs nth0/4). <lang Prolog> selection_sort([], []). selection_sort([H | L], [H1 | L2]) :- exchange(H, L, H1, L1), selection_sort(L1, L2).


exchange(H, [], H, []).

exchange(H, L, H1, L1) :- min_list(L, H2), ( H < H2 -> H1 = H, L1 = L ; H1 = H2,  % does the exchange of the number H  % and the min of the list nth0(Ind, L, H1, L2), nth0(Ind, L1, H, L2)). </lang>

PureBasic

<lang PureBasic>Procedure selectionSort(Array a(1))

 Protected i, j, lastIndex, minIndex
 
 lastIndex = ArraySize(a())
 For i = 0 To lastIndex - 1
   minIndex = i
   For j = i + 1 To lastIndex
     If a(minIndex) > a(j)
       minIndex = j
     EndIf
   Next
   Swap a(minIndex), a(i)
 Next  

EndProcedure</lang>

Python

<lang python>def selection_sort(lst):

   for i, e in enumerate(lst):
       mn = min(range(i,len(lst)), key=lst.__getitem__)
       lst[i], lst[mn] = lst[mn], e
   return lst</lang>

Qi

Translation of: sml

<lang qi>(define select-r

 Small []     Output -> [Small | (selection-sort Output)]
 Small [X|Xs] Output -> (select-r X Xs [Small|Output]) where (< X Small)
 Small [X|Xs] Output -> (select-r Small Xs [X|Output]))

(define selection-sort

 []          -> []
 [First|Lst] -> (select-r First Lst []))

(selection-sort [8 7 4 3 2 0 9 1 5 6]) </lang>

Quackery

<lang Quackery> [ 0 swap

   behead swap
   witheach
     [ 2dup > iff
         [ nip nip 
           i^ 1+ swap ] 
       else drop ]
   drop ]               is least ( [ --> n )
 [ [] swap 
   dup size times
     [ dup least pluck
       swap dip join ]
   drop ]               is ssort ( [ --> [ )
 [] 20 times [ 10 random join ]
 dup echo cr
 ssort echo cr</lang>
Output:
[ 5 2 5 0 4 5 1 5 1 1 0 3 7 2 0 9 6 1 8 7 ]
[ 0 0 0 1 1 1 1 2 2 3 4 5 5 5 5 6 7 7 8 9 ]

R

For loop: <lang r>selectionsort.loop <- function(x) {

  lenx <- length(x)
  for(i in seq_along(x))
  {
     mini <- (i - 1) + which.min(x[i:lenx])
     start_ <- seq_len(i-1)
     x <- c(x[start_], x[mini], x[-c(start_, mini)])
  }
  x

}</lang> Recursive:

(A prettier solution, but, you may need to increase the value of options("expressions") to test it. Also, you may get a stack overflow if the length of the input vector is more than a few thousand.) <lang r>selectionsort.rec <- function(x) {

  if(length(x) > 1)
  {
     mini <- which.min(x)
     c(x[mini], selectionsort(x[-mini]))
  } else x

}</lang>

Ra

<lang Ra> class SelectionSort **Sort a list with the Selection Sort algorithm**

on start

args := program arguments .sort(args) print args

define sort(list) is shared **Sort the list**

test list := [4, 2, 7, 3] .sort(list) assert list = [2, 3, 4, 7]

body count := list.count last := count - 1

for i in last

minCandidate := i j := i + 1

while j < count if list[j] < list[minCandidate], minCandidate := j j :+ 1

temp := list[i] list[i] := list[minCandidate] list[minCandidate] := temp </lang>

Racket

<lang racket>

  1. lang racket

(define (selection-sort xs)

 (cond [(empty? xs) '()]
       [else (define x0 (apply min xs))
             (cons x0 (selection-sort (remove x0 xs)))]))

</lang>

Raku

(formerly Perl 6) Solution 1: <lang perl6>sub selection_sort ( @a is copy ) {

   for 0 ..^ @a.end -> $i {
       my $min = [ $i+1 .. @a.end ].min: { @a[$_] };
       @a[$i, $min] = @a[$min, $i] if @a[$i] > @a[$min];
   }
   return @a;

}

my @data = 22, 7, 2, -5, 8, 4; say 'input = ' ~ @data; say 'output = ' ~ @data.&selection_sort; </lang>

Output:
input  = 22 7 2 -5 8 4
output = -5 2 4 7 8 22

Solution 2: <lang perl6>sub selectionSort(@tmp) {

   for ^@tmp -> $i {
       my $min = $i; @tmp[$i, $_] = @tmp[$_, $i] if @tmp[$min] > @tmp[$_] for $i^..^@tmp;
   }
   return @tmp;

} </lang>

Output:
input  = 22 7 2 -5 8 4
output = -5 2 4 7 8 22

REXX

<lang rexx>/*REXX program sorts a stemmed array using the selection─sort algorithm. */ call init /*assign some values to an array: @. */ call show 'before sort' /*show the before array elements. */

    say  copies('▒', 65)                        /*show a nice separator line  (fence). */

call selectionSort # /*invoke selection sort (and # items). */ call show ' after sort' /*show the after array elements. */ exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ init: @.=; @.1 = '---The seven hills of Rome:---'

                           @.2 = '==============================';      @.6 = 'Virminal'
                           @.3 = 'Caelian'                       ;      @.7 = 'Esquiline'
                           @.4 = 'Palatine'                      ;      @.8 = 'Quirinal'
                           @.5 = 'Capitoline'                    ;      @.9 = 'Aventine'
             do #=1  until @.#==;   end       /*find the number of items in the array*/
     #= #-1;         return                     /*adjust  #  (because of  DO  index).  */

/*──────────────────────────────────────────────────────────────────────────────────────*/ selectionSort: procedure expose @.; parse arg n

                     do j=1  for n-1;                 _= @.j;             p= j
                         do k=j+1  to n;      if @.k>=_  then iterate
                         _= @.k;      p= k      /*this item is out─of─order, swap later*/
                         end   /*k*/
                     if p==j  then iterate      /*if the same, the order of items is OK*/
                     _= @.j;  @.j= @.p;  @.p= _ /*swap 2 items that're out─of─sequence.*/
                     end       /*j*/
              return

/*──────────────────────────────────────────────────────────────────────────────────────*/ show: do i=1 for #; say ' element' right(i,length(#)) arg(1)":" @.i; end; return</lang>

output:
       element 1 before sort: ---The seven hills of Rome:---
       element 2 before sort: ==============================
       element 3 before sort: Caelian
       element 4 before sort: Palatine
       element 5 before sort: Capitoline
       element 6 before sort: Virminal
       element 7 before sort: Esquiline
       element 8 before sort: Quirinal
       element 9 before sort: Aventine
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
       element 1  after sort: ---The seven hills of Rome:---
       element 2  after sort: ==============================
       element 3  after sort: Aventine
       element 4  after sort: Caelian
       element 5  after sort: Capitoline
       element 6  after sort: Esquiline
       element 7  after sort: Palatine
       element 8  after sort: Quirinal
       element 9  after sort: Virminal

Ring

<lang ring> aList = [7,6,5,9,8,4,3,1,2,0] see sortList(aList)

func sortList list

    count = len(list) + 1
    last = count - 1
  
    for i = 1 to last
         minCandidate = i
         j = i + 1
         while j < count

if list[j] < list[minCandidate] minCandidate = j ok j = j + 1

         end
         temp = list[i]
         list[i] = list[minCandidate]
         list[minCandidate] = temp
     next
     return list

</lang>

Ruby

<lang ruby>

  1. a relatively readable version - creates a distinct array

def sequential_sort(array)

 sorted = []
 while array.any?
   index_of_smallest_element = find_smallest_index(array) # defined below
   sorted << array.delete_at(index_of_smallest_element)
 end
 sorted

end

def find_smallest_index(array)

 smallest_element = array[0]
 smallest_index = 0
 array.each_with_index do |ele, idx|
   if ele < smallest_element
     smallest_element = ele
     smallest_index = idx
   end
 end
 smallest_index

end

puts "sequential_sort([9, 6, 8, 7, 5]): #{sequential_sort([9, 6, 8, 7, 5])}"

  1. prints: sequential_sort([9, 6, 8, 7, 5]): [5, 6, 7, 8, 9]


  1. more efficient version - swaps the array's elements in place

def sequential_sort_with_swapping(array)

 array.each_with_index do |element, index|
   smallest_unsorted_element_so_far = element
   smallest_unsorted_index_so_far = index
   (index+1...array.length).each do |index_value|
     if array[index_value] < smallest_unsorted_element_so_far
       smallest_unsorted_element_so_far = array[index_value]
       smallest_unsorted_index_so_far = index_value
     end
   end
   # swap index_value-th smallest element for index_value-th element
   array[index], array[smallest_unsorted_index_so_far] = array[smallest_unsorted_index_so_far], array[index]
 end
 array

end

puts "sequential_sort_with_swapping([7,6,5,9,8,4,3,1,2,0]): #{sequential_sort_with_swapping([7,6,5,9,8,4,3,1,2,0])}"

  1. prints: sequential_sort_with_swapping([7,6,5,9,8,4,3,1,2,0]): [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

</lang>

Run BASIC

<lang runbasic>siz = 10 dim srdData(siz) for i = 1 to siz srtData(i) = rnd(0) * 100 next i

FOR i = 1 TO siz-1

  lo = i
  FOR j = (i + 1) TO siz
     IF srtData(j) < srtData(lo) lo = j
  NEXT j
  if i <> lo then
  temp        = srtData(i)
  srtData(i)  = srtData(lo)
  srtData(lo) = temp
  end if

NEXT i

for i = 1 to siz print i;chr$(9);srtData(i) next i</lang>

1	20.5576419
2	32.4299311
3	48.345375
4	54.135847
5	63.1427764
6	67.8079128
7	85.2134895
8	91.3576602
9	95.4280853
10	98.8323211

Rust

<lang rust> fn selection_sort(array: &mut [i32]) {

   let mut min;
   for i in 0..array.len() {
       min = i;
       for j in (i+1)..array.len() {
           if array[j] < array[min] {
               min = j;
           }
       }
       let tmp = array[i];
       array[i] = array[min];
       array[min] = tmp;
   }

}

fn main() {

   let mut array = [ 9, 4, 8, 3, -5, 2, 1, 6 ];
   println!("The initial array is {:?}", array);
   selection_sort(&mut array);
   println!(" The sorted array is {:?}", array);

} </lang>

Scala

<lang scala>def swap(a: Array[Int], i1: Int, i2: Int) = { val tmp = a(i1); a(i1) = a(i2); a(i2) = tmp }

def selectionSort(a: Array[Int]) =

 for (i <- 0 until a.size - 1) 
   swap(a, i, (i + 1 until a.size).foldLeft(i)((currMin, index) => 
     if (a(index) < a(currMin)) index else currMin))</lang>

This version avoids the extra definition by using a function literal:

<lang scala>def selectionSort(a: Array[Int]) = for (i <- 0 until a.size - 1) (

 { (i1: Int, i2: Int) => val tmp = a(i1); a(i1) = a(i2); a(i2) = tmp }
 ) (i, (i + 1 until a.size).foldLeft(i)((currMin, index) => if (a(index) < a(currMin)) index else currMin) )</lang>

Functional way: <lang scala>def selectionSort[T <% Ordered[T]](list: List[T]): List[T] = {

 def remove(e: T, list: List[T]): List[T] =
   list match {
     case Nil => Nil
     case x :: xs if x == e => xs
     case x :: xs => x :: remove(e, xs)
   }
 list match {
   case Nil => Nil
   case _ =>
     val min = list.min
     min :: selectionSort(remove(min, list))
 }

} </lang>

Seed7

<lang seed7>const proc: selectionSort (inout array elemType: arr) is func

 local
   var integer: i is 0;
   var integer: j is 0;
   var integer: min is 0;
   var elemType: help is elemType.value;
 begin
   for i range 1 to length(arr) - 1 do
     min := i;
     for j range i + 1 to length(arr) do
       if arr[j] < arr[min] then
         min := j;
       end if;
     end for;
     help := arr[min];
     arr[min] := arr[i];
     arr[i] := help;
   end for;
 end func;</lang>

Original source: [1]

Sidef

Translation of: Ruby

<lang ruby>class Array {

   method selectionsort {
       for i in ^(self.end) {
           var min_idx = i
           for j in (i+1 .. self.end) {
               if (self[j] < self[min_idx]) {
                   min_idx = j
               }
           }
           self.swap(i, min_idx)
       }
       return self
   }

}

var nums = [7,6,5,9,8,4,3,1,2,0]; say nums.selectionsort;

var strs = ["John", "Kate", "Zerg", "Alice", "Joe", "Jane"]; say strs.selectionsort;</lang>

Standard ML

<lang sml>fun selection_sort [] = []

 | selection_sort (first::lst) =
   let
     val (small, output) = foldl
       (fn (x, (small, output)) =>
           if x < small then 
             (x, small::output)
           else
             (small, x::output)
       ) (first, []) lst
   in
     small :: selection_sort output
   end</lang>

Stata

<lang stata>mata function selection_sort(real vector a) { real scalar i, j, k, n n = length(a) for (i = 1; i < n; i++) { k = i for (j = i+1; j <= n; j++) { if (a[j] < a[k]) k = j } if (k != i) a[(i, k)] = a[(k, i)] } } end</lang>

Swift

<lang Swift>func selectionSort(inout arr:[Int]) {

   var min:Int
   
   for n in 0..<arr.count {
       min = n
       
       for x in n+1..<arr.count {
           if (arr[x] < arr[min]) {
               min = x
           }
       }
       
       if min != n {
           let temp = arr[min]
           arr[min] = arr[n]
           arr[n] = temp
       }
   }

}</lang>

Tcl

Library: Tcllib (Package: struct::list)

<lang tcl>package require Tcl 8.5 package require struct::list

proc selectionsort {A} {

   set len [llength $A]
   for {set i 0} {$i < $len - 1} {incr i} {
       set min_idx [expr {$i + 1}]
       for {set j $min_idx} {$j < $len} {incr j} {
           if {[lindex $A $j] < [lindex $A $min_idx]} {
               set min_idx $j
           }
       }
       if {[lindex $A $i] > [lindex $A $min_idx]} {
           struct::list swap A $i $min_idx
       }
   }
   return $A

}

puts [selectionsort {8 6 4 2 1 3 5 7 9}] ;# => 1 2 3 4 5 6 7 8 9</lang>

TI-83 BASIC

Store input into L1 and prgmSORTSLCT will store the sorted output into L2.

:L1→L2
:dim(L2)→I
:For(A,1,I)
:A→C
:0→X
:For(B,A,I)
:If L2(B)<L2(C)
:Then
:B→C
:1→X
:End
:End
:If X=1
:Then
:L2(C)→B
:L2(A)→L2(C)
:B→L2(A)
:End
:End
:DelVar A
:DelVar B
:DelVar C
:DelVar I
:DelVar X
:Return

uBasic/4tH

<lang>PRINT "Selection sort:"

 n = FUNC (_InitArray)
 PROC _ShowArray (n)
 PROC _Selectionsort (n)
 PROC _ShowArray (n)

PRINT

END


_Selectionsort PARAM (1) ' Selection sort

 LOCAL (3)
 FOR b@ = 0 TO a@-1
   c@ = b@
   FOR d@ = b@ TO a@-1
     IF @(d@) < @(c@) THEN c@ = d@
   NEXT
   IF b@ # c@ THEN PROC _Swap (b@, c@)
 NEXT

RETURN


_Swap PARAM(2) ' Swap two array elements

 PUSH @(a@)
 @(a@) = @(b@)
 @(b@) = POP()

RETURN


_InitArray ' Init example array

 PUSH 4, 65, 2, -31, 0, 99, 2, 83, 782, 1

 FOR i = 0 TO 9
   @(i) = POP()
 NEXT

RETURN (i)


_ShowArray PARAM (1) ' Show array subroutine

 FOR i = 0 TO a@-1
   PRINT @(i),
 NEXT

 PRINT

RETURN</lang>

Ursala

The selection_sort function is parameterized by a relational predicate p. There are no arrays in Ursala so it uses a list, and the selected item is deleted from the list and inserted into another on each iteration rather than swapped with a preceding item of the same list. <lang Ursala>#import std

selection_sort "p" = @iNX ~&l->rx ^(gldif ==,~&r)^/~&l ^|C/"p"$- ~&</lang> This is already a bad way to code a sorting algorithm in this language, but with only a bit more work, we can get a bigger and slower version that more closely simulates the operations of repeatedly reordering an array. <lang Ursala>selection_sort "p" = ~&itB^?a\~&a ^|JahPfatPRC/~& ~=-~BrhPltPClhPrtPCTlrTQrS^D/"p"$- ~&</lang> Here is a test program sorting by the partial order relation on natural numbers. <lang Ursala>#import nat

  1. cast %nL

example = selection_sort(nleq) <294,263,240,473,596,392,621,348,220,815></lang>

Output:
<220,240,263,294,348,392,473,596,621,815>

VBA

I shameless stole the swap function from the bubblesort VBscript implementation.

<lang VBA> sub swap( byref a, byref b) dim tmp tmp = a a = b b = tmp end sub

function selectionSort (a) for i = 0 to ubound(a) k = i for j=i+1 to ubound(a) if a(j) < a(i) then swap a(i), a(j) end if next next selectionSort = a end function </lang>

VBScript

<lang vb>Function Selection_Sort(s) arr = Split(s,",") For i = 0 To UBound(arr) For j = i To UBound(arr) temp = arr(i) If arr(j) < arr(i) Then arr(i) = arr(j) arr(j) = temp End If Next Next Selection_Sort = (Join(arr,",")) End Function

WScript.StdOut.Write "Pre-Sort" & vbTab & "Sorted" WScript.StdOut.WriteLine WScript.StdOut.Write "3,2,5,4,1" & vbTab & Selection_Sort("3,2,5,4,1") WScript.StdOut.WriteLine WScript.StdOut.Write "c,e,b,a,d" & vbTab & Selection_Sort("c,e,b,a,d")</lang>

Output:
Pre-Sort	Sorted
3,2,5,4,1	1,2,3,4,5
c,e,b,a,d	a,b,c,d,e

Wren

Translation of: Go

<lang ecmascript>var selectionSort = Fn.new { |a|

   var last = a.count - 1
   for (i in 0...last) {
       var aMin = a[i]
       var iMin = i
       for (j in i+1..last) {
           if (a[j] < aMin) {
               aMin = a[j]
               iMin = j
           }
       }
       var t = a[i]
       a[i] = aMin
       a[iMin] = t
   }

}

var as = [ [4, 65, 2, -31, 0, 99, 2, 83, 782, 1], [7, 5, 2, 6, 1, 4, 2, 6, 3] ] for (a in as) {

   System.print("Before: %(a)")
   selectionSort.call(a)
   System.print("After : %(a)")
   System.print()

}</lang>

Output:
Before: [4, 65, 2, -31, 0, 99, 2, 83, 782, 1]
After : [-31, 0, 1, 2, 2, 4, 65, 83, 99, 782]

Before: [7, 5, 2, 6, 1, 4, 2, 6, 3]
After : [1, 2, 2, 3, 4, 5, 6, 6, 7]


Alternatively we can just call a library method.

Library: Wren-sort

<lang ecmascript>import "/sort" for Sort

var as = [ [4, 65, 2, -31, 0, 99, 2, 83, 782, 1], [7, 5, 2, 6, 1, 4, 2, 6, 3] ] for (a in as) {

   System.print("Before: %(a)")
   Sort.selection(a)
   System.print("After : %(a)")
   System.print()

}</lang>

Output:
As above.

XPL0

<lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations string 0; \use zero-terminated strings

proc SelSort(A, N); \Selection sort char A; \address of array int N; \number of elements in array (size) int I, J, S, JS, T; [for I:= 0 to N-2 do

       [S:= (~0)>>1;
       for J:= I to N-1 do     \find smallest element
               if A(J) < S then [S:= A(J);  JS:= J];
       T:= A(I);  A(I):= A(JS);  A(JS):= T;
       ];

];

func StrLen(Str); \Return number of characters in an ASCIIZ string char Str; int I; for I:= 0 to -1>>1-1 do

       if Str(I) = 0 then return I;

char Str; [Str:= "Pack my box with five dozen liquor jugs."; SelSort(Str, StrLen(Str)); Text(0, Str); CrLf(0); ]</lang>

Output:
       .Pabcdeefghiiijklmnoooqrstuuvwxyz

zkl

<lang zkl>fcn selectionSort(list){ // sort a list of ints

  copy,r:=list.copy(),List();
  while(copy){
     min,idx:=(0).min(copy), copy.find(min);
     r.append(min);
     copy.del(idx);
  }
  r

}</lang> <lang zkl>selectionSort(List(28, 44, 46, 24, 19, -5, 2, 17, 11, 25, 4)).println();</lang>

Output:
L(-5,2,4,11,17,19,24,25,28,44,46)