Sorting algorithms/Cycle sort: Difference between revisions
Content added Content deleted
(J) |
(Added Perl Implementation) |
||
Line 314: | Line 314: | ||
This took 4 writes.</pre> |
This took 4 writes.</pre> |
||
=={{header|Perl}}== |
|||
This is based on the Wikipedia pseudocode. |
|||
<lang perl>use strict; |
|||
use warnings; |
|||
sub cycleSort(@) { |
|||
my ($array) = @_; |
|||
my $writes = 0; |
|||
my @alreadysorted; |
|||
# For each index except the last: |
|||
for my $start ( 0 .. $#$array - 1 ) { |
|||
next if $alreadysorted[$start]; |
|||
my $item = $array->[$start]; |
|||
# If there are N items less than $item, then we |
|||
# must move $item N items rightward. |
|||
my $pos = $start + grep $array->[$_] lt $item, $start + 1 .. $#$array; |
|||
# If the item is where it should be, continue. |
|||
next if $pos == $start; |
|||
# If $item is one of several repetitions, move it to the right |
|||
# of the last repeat. |
|||
++$pos while $item eq $array->[ $pos ]; |
|||
# Store $item at $pos, where it belongs, and fetch the |
|||
# value that had been at $pos, and put it in $item. |
|||
($array->[ $pos ], $item) = ($item, $array->[ $pos ]); |
|||
++$writes; |
|||
# Whatever $item is now, it certainly doesn't belong at $pos; |
|||
do { |
|||
# Find the correct $pos, |
|||
$pos = $start + grep $array->[$_] lt $item, $start+1 .. $#$array; |
|||
++$pos while $item eq $array->[ $pos ]; |
|||
# Swap the value there with $item, |
|||
($array->[ $pos ] , $item ) = ($item, $array->[ $pos ]); |
|||
# And mark $pos as having the correct value in it.. |
|||
$alreadysorted[ $pos ] = 1; |
|||
++$writes; |
|||
# The loop ends after we have just written an item to $start |
|||
} while $pos != $start; |
|||
} |
|||
$writes; |
|||
} |
|||
use List::Util 'shuffle'; |
|||
my @test = shuffle( ('a'..'z') x 2 ); |
|||
print "Before sorting: @test\n"; |
|||
print "There were ", cycleSort( \@test ), " writes\n"; |
|||
print "After sorting: @test\n"; |
|||
</lang> |
|||
{{out}} |
|||
<pre>Before sorting: a t d b f g y l t p w c r r x i y j k i z q e v a f o q j u x k m h s u v z g m b o l e n h p n c s w d |
|||
There were 50 writes |
|||
After sorting: a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z</pre> |
|||
=={{header|Perl 6}}== |
=={{header|Perl 6}}== |
||
<lang perl6>sub cycle_sort ( @nums is rw ) { |
<lang perl6>sub cycle_sort ( @nums is rw ) { |