Jump to content

Sorting algorithms/Quicksort: Difference between revisions

imported>Rcmlz
imported>Rcmlz
Line 8,228:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line># Empty list sorts to the empty list
multi#| Recursive, quicksort([]) { () }implementation
multi quicksort(@unsorted where @unsorted.elems < 2) { @unsorted }
multi quicksort([$pivot, *@rest]unsorted) {
# Otherwise, extract first item as pivot...
my $pivot = @unsorted.pick;
multi quicksort([$pivot, *@rest]) {
my %class{Order} is default([]);
# Partition.
%class my $before := @restunsorted.grep(classify: * beforecmp $pivot);
|quicksort(%class{Less}), |%class{Same}, |quicksort(%class{More})
my $equiv := @rest.grep(* eqv $pivot);
}
my $after := @rest.grep(* after $pivot);
}</syntaxhighlight>
 
The partitions can be sorted in parallel.
# Sort the partitions.
flat quicksort($before), $pivot, $equiv, quicksort($after)
}</syntaxhighlight>
Note that <code>$before</code> and <code>$after</code> are bound to lazy lists. The partitions can be sorted in parallel.
 
<syntaxhighlight lang="raku" line>
#|« Recursive, concurrentparallel, quicksort implementation
multi quicksort-parallel(@unsorted where @unsorted.elems < 2) { @unsorted }
 
multi quicksort-parallel(@unsorted) {
* in partitioning/classifying step by .race or .hyper
my %class{Order} is default([]);
* in recursion step on Less partition by start {}
my $pivot = @unsorted.pick;
»
%class = @input.raceunsorted.classify( * cmp $pivot );
sub quicksort-recursive-concurrent(@input) {
my $less = start { %partiton{Less}:exists ?? samewith(%partitonclass{Less}) !! [] };
return @input if @input.elems < 2;
my $pivotmore = @input.picksamewith(%class{More});
await $less andthen |$less.result, |%partitonclass{Same}, |$more
@input.race.classify( * cmp $pivot )
andthen
{
my %partiton = $_;
my $less = start { %partiton{Less}:exists ?? samewith(%partiton{Less}) !! [] };
my $more = %partiton{More}:exists ?? samewith(%partiton{More}) !! [];
await $less andthen |$less.result, |%partiton{Same}, |$more
}
}
#=« Implementation Notes:
* nouse needthe to start a newcurrent thread for More partition - as we better use current thread.
* recursion on the Less partition can create a large number of new threads -> limit it!
* hyper/race using default batch=64 and degree=4 -> tune it!
* samewith() refactors out the actual name of the routine.
* recursion on the Less partition can create a large number of new threads -> limit it!
* samewith() refactors out the actual name of the routine.
* andthen passes the result of the previous block as $_ to the next block.
»
</syntaxhighlight>
Line 8,283 ⟶ 8,272:
<a 🎮 3 z 4 🐧> => <a 🎮 3 z 4 🐧>.sort,
;
for &quicksort, &quicksort-recursive-parallel -> &fun {
say &fun.name;
is-deeply &fun(.key), .value, .key ~ "\t- =>\t " ~ .value for @testcases;
}
</syntaxhighlight>
<pre>
quicksort
ok 1 - =>
ok 2 - a => a
ok 3 - a a => a a
ok 4 - a b => a b
ok 5 - b a => a b
ok 6 - h b a c d f e g => a b c d e f g h
ok 7 - 2 3 1 4 5 => 1 2 3 4 5
ok 8 - a 🎮 3 z 4 🐧 => 3 4 a z 🎮 🐧
quicksort-parallel
ok 9 - =>
ok 10 - a => a
ok 11 - a a => a a
ok 12 - a b => a b
ok 13 - b a => a b
ok 14 - h b a c d f e g => a b c d e f g h
ok 15 - 2 3 1 4 5 => 1 2 3 4 5
ok 16 - a 🎮 3 z 4 🐧 => 3 4 a z 🎮 🐧
</pre>
 
=={{header|Red}}==
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.