June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -1,7 +1,11 @@
|
|||
{{Sorting Algorithm}}
|
||||
{{Wikipedia|Counting sort}}
|
||||
|
||||
|
||||
;Task:
|
||||
Implement the [[wp:Counting sort|Counting sort]]. This is a way of sorting integers when the minimum and maximum value are known.
|
||||
|
||||
|
||||
Pseudocode:
|
||||
'''function''' ''countingSort''(array, min, max):
|
||||
count: '''array of''' (max - min + 1) '''elements'''
|
||||
|
|
@ -21,3 +25,4 @@ Pseudocode:
|
|||
The ''min'' and ''max'' can be computed apart, or be known ''a priori''.
|
||||
|
||||
'''Note''': we know that, given an array of integers, its maximum and minimum values can be always found; but if we imagine the worst case for an array of 32 bit integers, we see that in order to hold the counts, we need an array of 2<sup>32</sup> elements, i.e., we need, to hold a count value up to 2<sup>32</sup>-1, more or less 4 Gbytes. So the counting sort is more practical when the range is (very) limited and minimum and maximum values are known ''a priori''. (Anyway sparse arrays may limit the impact of the memory usage)
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
# counting sort
|
||||
|
||||
n = 10
|
||||
|
||||
dim test(n)
|
||||
test = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1}
|
||||
|
||||
mn = -31
|
||||
mx = 782
|
||||
|
||||
dim cnt(mx - mn + 1) # count is a reserved string function name
|
||||
|
||||
# seems initialized as 0
|
||||
# for i = 1 to n
|
||||
# print cnt[i]
|
||||
# next i
|
||||
|
||||
# sort
|
||||
for i = 0 to n-1
|
||||
cnt[test[i] - mn] = cnt[test[i] - mn] + 1
|
||||
next i
|
||||
|
||||
# output
|
||||
print "original"
|
||||
for i = 0 to n-1
|
||||
print test[i] + " ";
|
||||
next i
|
||||
print
|
||||
print "ordered"
|
||||
for i = 0 to mx - mn
|
||||
if 0 < cnt[i] then # for i = k to 0 causes error
|
||||
for k = 1 to cnt[i]
|
||||
print i + mn + " ";
|
||||
next k
|
||||
endif
|
||||
next i
|
||||
print
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import extensions.
|
||||
import system'routines.
|
||||
|
||||
extension $op
|
||||
{
|
||||
countingSort
|
||||
= self clone; countingSort(self minimalMember, self maximalMember).
|
||||
|
||||
countingSort int:min int:max
|
||||
[
|
||||
array<int> count := int<>(max - min + 1).
|
||||
int z := 0.
|
||||
|
||||
count populate(:i)<int>(0).
|
||||
|
||||
0 till(self length) do(:i) [ count[self[i] - min] += 1 ].
|
||||
|
||||
min to:max do(:i)
|
||||
[
|
||||
while (count[i - min] > 0)
|
||||
[
|
||||
self[z] := i.
|
||||
z += 1.
|
||||
|
||||
count[i - min] -= 1.
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
program =
|
||||
[
|
||||
var list := 0 to:10 repeat(:i)(randomGenerator eval(10)); toArray.
|
||||
|
||||
console printLine("before:", list).
|
||||
console printLine("after :", list countingSort).
|
||||
].
|
||||
|
|
@ -21,10 +21,14 @@ contains
|
|||
integer, dimension(tmin:tmax) :: cnt
|
||||
integer :: i, z
|
||||
|
||||
forall(i=tmin:tmax)
|
||||
cnt(i) = count(array == i)
|
||||
end forall
|
||||
|
||||
cnt = 0 ! Initialize to zero to prevent false counts
|
||||
FORALL (I=1:Z) ! Not sure that this gives any benefit over a DO loop.
|
||||
cnt(array(i)) = cnt(array(i))+1
|
||||
END FORALL
|
||||
!
|
||||
! ok - cnt contains the frequency of every value
|
||||
! let's unwind them into the original array
|
||||
!
|
||||
z = 1
|
||||
do i = tmin, tmax
|
||||
do while ( cnt(i) > 0 )
|
||||
|
|
|
|||
|
|
@ -1,33 +1,20 @@
|
|||
function countsort{T<:Integer}(a::Array{T,1})
|
||||
(lo, hi) = extrema(a)
|
||||
b = zeros(T, length(a))
|
||||
cnt = zeros(Int, hi - lo + 1)
|
||||
for i in a
|
||||
cnt[i - lo + 1] += 1
|
||||
end
|
||||
z = one(Int)
|
||||
function countsort(a::Vector{<:Integer})
|
||||
lo, hi = extrema(a)
|
||||
b = zeros(a)
|
||||
cnt = zeros(eltype(a), hi - lo + 1)
|
||||
for i in a cnt[i-lo+1] += 1 end
|
||||
z = 1
|
||||
for i in lo:hi
|
||||
while cnt[i - lo + 1] > 0
|
||||
while cnt[i-lo+1] > 0
|
||||
b[z] = i
|
||||
z += 1
|
||||
cnt[i - lo + 1] -= 1
|
||||
cnt[i-lo+1] -= 1
|
||||
end
|
||||
end
|
||||
return b
|
||||
end
|
||||
|
||||
a = Uint8[rand(1:typemax(Uint8)) for i in 1:20]
|
||||
println("Sort of Unsigned Bytes:")
|
||||
println(" Before Sort:")
|
||||
println(" ", a)
|
||||
a = countsort(a)
|
||||
println("\n After Sort:")
|
||||
println(" ", a, "\n")
|
||||
|
||||
a = [rand(1:2^10) for i in 1:20]
|
||||
println("Sort of Integers:")
|
||||
println(" Before Sort:")
|
||||
println(" ", a)
|
||||
a = countsort(a)
|
||||
println("\n After Sort:")
|
||||
println(" ", a)
|
||||
v = rand(UInt8, 20)
|
||||
println("# unsorted bytes: $v\n -> sorted bytes: $(countsort(v))")
|
||||
v = rand(1:2 ^ 10, 20)
|
||||
println("# unsorted integers: $v\n -> sorted integers: $(countsort(v))")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
sub counting-sort (@ints) {
|
||||
my $off = @ints.min;
|
||||
(my @counts)[$_ - $off]++ for @ints;
|
||||
flat @counts.kv.map: { ($^k + $off) xx ($^v // 0) }
|
||||
}
|
||||
|
||||
# Testing:
|
||||
constant @age-range = 2 .. 102;
|
||||
my @ages = @age-range.roll(50);
|
||||
say @ages.&counting-sort;
|
||||
say @ages.sort;
|
||||
|
||||
say @ages.&counting-sort.join eq @ages.sort.join ?? 'ok' !! 'not ok';
|
||||
|
|
@ -1,17 +1,21 @@
|
|||
/*REXX program sorts an array using the count─sort algorithm. */
|
||||
/*REXX pgm sorts an array of integers (can be negative) using the count─sort algorithm.*/
|
||||
$=1 3 6 2 7 13 20 12 21 11 22 10 23 9 24 8 25 43 62 42 63 41 18 42 17 43 16 44 15 45 14 46 79 113 78 114 77 39 78 38
|
||||
#=words($); w=length(#); do i=1 for #
|
||||
@.i=word($,i) /*get a Recaman # from a list.*/
|
||||
end /*i*/
|
||||
call show 'before sort: ' /*show the before array elements. */
|
||||
say copies('▒',55) /*show a pretty separator line. */
|
||||
call countSort # /*sort a number of entries of @. array.*/
|
||||
call show ' after sort: ' /*show the after array elements. */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
countSort: procedure expose @.; parse arg N; L=@.1; h=L; _.=0; x=1
|
||||
do j=1 for N; z=@.j; _.z=_.z+1; L=min(L,@.j); h=max(h,@.j); end /*j*/
|
||||
do k=L to h; do x=x for _.k; @.x=k; end /*x*/; end /*k*/
|
||||
return
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
show: do s=1 for #; say right("element",20) right(s,w) arg(1) @.s; end; return
|
||||
#=words($); w=length(#) /* [↑] a list of some Recaman numbers.*/
|
||||
m=0; _.=0 /*M: max width of any number in @. */
|
||||
do i=1 for #; z=word($, i); @.i=z; m=max(m, length(z)) /*get from $ list. */
|
||||
if i==1 then do; LO=z; HI=z; end /*assume z: LO & HI*/
|
||||
_.z= _.z + 1; LO=min(LO, z); HI=max(HI, z) /*find the LO & HI.*/
|
||||
end /*i*/
|
||||
/*W: max index width for the @. array*/
|
||||
call show 'before sort: ' /*show the before array elements. */
|
||||
say copies('▒', 55) /*show a separator line (before/after).*/
|
||||
call countSort # /*sort a number of entries of @. array.*/
|
||||
call show ' after sort: ' /*show the after array elements. */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
countSort: parse arg N; x=1
|
||||
do k=LO to HI; do x=x for _.k; @.x=k; end /*x*/
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
show: do s=1 for #; say right("element",20) right(s,w) arg(1) right(@.s,m); end; return
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
fn counting_sort(
|
||||
mut data: Vec<usize>,
|
||||
min: usize,
|
||||
max: usize,
|
||||
) -> Vec<usize> {
|
||||
// create and fill counting bucket with 0
|
||||
let mut count: Vec<usize> = Vec::with_capacity(data.len());
|
||||
count.resize(data.len(), 0);
|
||||
|
||||
for num in &data {
|
||||
count[num - min] = count[num - min] + 1;
|
||||
}
|
||||
let mut z: usize = 0;
|
||||
for i in min..max+1 {
|
||||
while count[i - min] > 0 {
|
||||
data[z] = i;
|
||||
z += 1;
|
||||
count[i - min] = count[i - min] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
data
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let arr1 = vec![1, 0, 2, 9, 3, 8, 4, 7, 5, 6];
|
||||
println!("{:?}", counting_sort(arr1, 0, 9));
|
||||
|
||||
let arr2 = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
println!("{:?}", counting_sort(arr2, 0, 9));
|
||||
|
||||
let arr3 = vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
|
||||
println!("{:?}", counting_sort(arr3, 0, 10));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue