Sorting algorithms/Selection sort

From Rosetta Code

(Redirected from Selection sort)
Jump to: navigation, search
Sorting algorithms/Selection sort is a programming task. Visitors like you are encouraged to solve it according to the task description, using any language they may happen to know.
Add to BlogMarksAdd to del.icio.usAdd to diggAdd to NewsvineAdd to redditAdd to Slashdot

Sorting Algorithm
This is a sorting algorithm. It may be applied to a set of data in order to sort it.

For other sorting algorithms, see Category:Sorting Algorithms, or:
Bogosort | Bubble Sort | Cocktail Sort | Comb Sort | Counting Sort | Gnome Sort | Heapsort | Insertion Sort | Mergesort | Permutation Sort | Quicksort | Selection Sort | Shell Sort

In this task, the goal is to 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.

Contents

[edit] 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;
}

[edit] 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;

Sample output:

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

[edit] 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

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))

Output:

     abcdefghiijklmnopqrstuvwxyz
big fjords vex quick waltz nymph

[edit] AutoHotkey

ahk forum: discussion

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
}

[edit] 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]
}
}

[edit] C

#include <stdio.h>
 
 
int getminindex(int *a, int s, int b)
{
int i, min=a[s], mi=s;
for(i=s; i < b; i++)
{
if ( a[i] < min ) { min = a[i]; mi = i; }
}
return mi;
}
 
void selectionsort(int *a, int s)
{
int i, t, mi;
for(i=0; i<s ; i++)
{
mi = getminindex(a, i, s);
t = a[i]; a[i] = a[mi]; a[mi] = t;
}
}
 
 
int main()
{
int ar[] = { 5, 200, 1, 65, 30, 99, 2, 0 };
int i;
 
selectionsort(ar, 8);
for(i=0; i<8; i++)
{
printf("%d\n", ar[i]);
}
 
return 0;
}

Sample output

0
1
2
5
30
65
99
200

[edit] C++

Compiler: g++ (version 4.3.2 20081105 (Red Hat 4.3.2-7))

#include <algorithm>
#include <iterator>
 
template<typename ForwardIterator>
void selectionSort(ForwardIterator begin, ForwardIterator end) {
ForwardIterator i = begin;
while(i != end) {
ForwardIterator j = i;
ForwardIterator min = i;
while(j != end) {
if(*j < *min) {
min = j;
}
++j;
}
std::iter_swap(i, min);
++i;
}
}

[edit] C#

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

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;
}
}

Example of usage:

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]);
}

Output:

a
generic
is
of
selection
sort
test
this


[edit] Clojure

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

(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))))

[edit] Common 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))))

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)

[edit] D

// Written in D 2.0.
 
import std.stdio;
 
void swap(T)(ref T lhs, ref T rhs) {
T temp = lhs;
lhs = rhs;
rhs = temp;
}
 
void selectionSort(T)(T[] data) {
foreach(i; 0..data.length) {
size_t minIndex = i;
foreach(j; i + 1..data.length) {
if(data[j] < data[minIndex]) {
minIndex = j;
}
}
swap(data[i], data[minIndex]);
}
}
 
void main() {
auto foo = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2];
selectionSort(foo);
writeln(foo);
}

[edit] 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))
}
}
}

[edit] 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

[edit] Fortran

Works with: Fortran version 95 and later

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

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

[edit] Haskell

selectionSort [] = []
selectionSort (first:lst) = selectR first [] lst where
selectR small output [] = small : selectionSort output
selectR small output (x:xs) | x < small = selectR x (small:output) xs
| otherwise = selectR small (x:output) xs

[edit] HaXe

static function selectionSort(arr:Array<Int>) {
var len = arr.length;
for (index in 0...len)
{
var minIndex = index;
for (remainingIndex in (index+1)...len)
{
if (arr[minIndex] > arr[remainingIndex]) {
minIndex = remainingIndex;
}
}
if (index != minIndex) {
var temp = arr[index];
arr[index] = arr[minIndex];
arr[minIndex] = temp;
}
}
}

[edit] J

Create the following script and load it to a J session.

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
)

In an email discussion, Roger_Hui presented the following tacit code:

ix=: C.~ <@~.@(0, (i. <./)) 
ss1=: ({. , $:@}.)@ix^:(*@#)

To validate:

   [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

[edit] Java

This algorithm sorts in place. The call sort(array) will rearrange the array and not create a new one.

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;
}
}

[edit] 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

[edit] 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

[edit] Oz

Although lists are much more used in Oz than arrays, this algorithm seems more natural for arrays.

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}}

[edit] Perl

Translation of: Tcl

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;}

[edit] 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

[edit] Python

def selectionSort(lst):
for i in range(0,len(lst)-1):
mn = min(range(i,len(lst)), key=lst.__getitem__)
lst[i],lst[mn] = lst[mn],lst[i]
return lst

[edit] R

For loop:

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
}

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.)

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

[edit] Ruby

Translation of: Tcl

class Array
def selectionsort!
0.upto(length - 2) do |i|
(min_idx = i + 1).upto(length - 1) do |j|
if self[j] < self[min_idx]
min_idx = j
end
end
if self[i] > self[min_idx]
self[i], self[min_idx] = self[min_idx], self[i]
end
end
self
end
end
ary = [7,6,5,9,8,4,3,1,2,0]
ary.selectionsort!
# => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[edit] 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))

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

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) )

[edit] Standard ML

fun selection_sort [] = []
| selection_sort (first::lst) =
let
fun select_r small ([], output) = small :: selection_sort output
| select_r small (x::xs, output) =
if x < small then
select_r x (xs, small::output)
else
select_r small (xs, x::output)
in
select_r first (lst, [])
end

[edit] Tcl

Uses struct::list package from Library: tcllib

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

[edit] 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

[edit] 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.

#import std
 
selection_sort "p" = @iNX ~&l->rx ^(gldif ==,~&r)^/~&l ^|C/"p"$- ~&

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.

selection_sort "p" = ~&itB^?a\~&a ^|JahPfatPRC/~& ~=-~BrhPltPClhPrtPCTlrTQrS^D/"p"$- ~&

Here is a test program sorting by the partial order relation on natural numbers.

#import nat
#cast %nL
 
example = selection_sort(nleq) <294,263,240,473,596,392,621,348,220,815>

output:

<220,240,263,294,348,392,473,596,621,815>
Personal tools
Google AdSense