all tasks
This commit is contained in:
parent
b83f433714
commit
68f8f3e56b
14735 changed files with 178959 additions and 0 deletions
2
Task/Sorting-algorithms-Radix-sort/0DESCRIPTION
Normal file
2
Task/Sorting-algorithms-Radix-sort/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
{{Sorting Algorithm}}
|
||||
In this task, the goal is to sort an integer array with the [[wp:Radix sort|radix sort algorithm]]. The primary purpose is to complete the characterization of sort algorithms task.
|
||||
2
Task/Sorting-algorithms-Radix-sort/1META.yaml
Normal file
2
Task/Sorting-algorithms-Radix-sort/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Sorting Algorithms
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
with Ada.Text_IO;
|
||||
procedure Radix_Sort is
|
||||
type Integer_Array is array (Positive range <>) of Integer;
|
||||
|
||||
procedure Least_Significant_Radix_Sort (Data : in out Integer_Array; Base : Positive := 10) is
|
||||
type Bucket is record
|
||||
Count : Natural := 0;
|
||||
Content : Integer_Array (Data'Range);
|
||||
end record;
|
||||
|
||||
subtype Bucket_Index is Integer range -Base + 1 .. Base - 1;
|
||||
type Bucket_Array is array (Bucket_Index) of Bucket;
|
||||
|
||||
procedure Append (To : in out Bucket; Item : Integer) is
|
||||
begin
|
||||
To.Count := To.Count + 1;
|
||||
To.Content (To.Count) := Item;
|
||||
end Append;
|
||||
|
||||
function Get_Nth_Digit (Value : Integer; N : Positive) return Integer is
|
||||
Result : Integer := (Value / (Base ** (N - 1))) mod Base;
|
||||
begin
|
||||
if Value < 0 then
|
||||
Result := -Result;
|
||||
end if;
|
||||
return Result;
|
||||
end Get_Nth_Digit;
|
||||
|
||||
function Get_Maximum return Natural is
|
||||
Result : Natural := 0;
|
||||
begin
|
||||
for I in Data'Range loop
|
||||
if abs (Data (I)) > Result then
|
||||
Result := abs (Data (I));
|
||||
end if;
|
||||
end loop;
|
||||
return Result;
|
||||
end Get_Maximum;
|
||||
|
||||
function Split (Pass : Positive) return Bucket_Array is
|
||||
Buckets : Bucket_Array;
|
||||
begin
|
||||
for I in Data'Range loop
|
||||
Append (To => Buckets (Get_Nth_Digit (Data (I), Pass)),
|
||||
Item => Data (I));
|
||||
end loop;
|
||||
return Buckets;
|
||||
end Split;
|
||||
|
||||
function Merge (Buckets : Bucket_Array) return Integer_Array is
|
||||
Result : Integer_Array (Data'Range);
|
||||
Current_Index : Positive := 1;
|
||||
begin
|
||||
for Sublist in Buckets'Range loop
|
||||
for Item in 1 .. Buckets (Sublist).Count loop
|
||||
Result (Current_Index) := Buckets (Sublist).Content (Item);
|
||||
Current_Index := Current_Index + 1;
|
||||
end loop;
|
||||
end loop;
|
||||
return Result;
|
||||
end Merge;
|
||||
|
||||
Max_Number : Natural := Get_Maximum;
|
||||
Digit_Count : Positive := 1;
|
||||
begin
|
||||
-- count digits of biggest number
|
||||
while Max_Number > Base loop
|
||||
Digit_Count := Digit_Count + 1;
|
||||
Max_Number := Max_Number / Base;
|
||||
end loop;
|
||||
for Pass in 1 .. Digit_Count loop
|
||||
Data := Merge (Split (Pass));
|
||||
end loop;
|
||||
end Least_Significant_Radix_Sort;
|
||||
|
||||
Test_Array : Integer_Array := (170, 45, 75, -90, -802, 24, 2, 66);
|
||||
begin
|
||||
Least_Significant_Radix_Sort (Test_Array, 4);
|
||||
for I in Test_Array'Range loop
|
||||
Ada.Text_IO.Put (Integer'Image (Test_Array (I)));
|
||||
end loop;
|
||||
Ada.Text_IO.New_Line;
|
||||
end Radix_Sort;
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
DIM test%(9)
|
||||
test%() = 4, 65, 2, -31, 0, 99, 2, 83, 782, 1
|
||||
PROCradixsort(test%(), 10, 10)
|
||||
FOR i% = 0 TO 9
|
||||
PRINT test%(i%) ;
|
||||
NEXT
|
||||
PRINT
|
||||
END
|
||||
|
||||
DEF PROCradixsort(a%(), n%, r%)
|
||||
LOCAL d%, e%, i%, l%, m%, b%(), bucket%()
|
||||
DIM b%(n%-1), bucket%(r%-1)
|
||||
FOR i% = 0 TO n%-1
|
||||
IF a%(i%) < l% l% = a%(i%)
|
||||
IF a%(i%) > m% m% = a%(i%)
|
||||
NEXT
|
||||
a%() -= l%
|
||||
m% -= l%
|
||||
e% = 1
|
||||
WHILE m% DIV e%
|
||||
bucket%() = 0
|
||||
FOR i% = 0 TO n%-1
|
||||
bucket%(a%(i%) DIV e% MOD r%) += 1
|
||||
NEXT
|
||||
FOR i% = 1 TO r%-1
|
||||
bucket%(i%) += bucket%(i% - 1)
|
||||
NEXT
|
||||
FOR i% = n%-1 TO 0 STEP -1
|
||||
d% = a%(i%) DIV e% MOD r%
|
||||
bucket%(d%) -= 1
|
||||
b%(bucket%(d%)) = a%(i%)
|
||||
NEXT
|
||||
a%() = b%()
|
||||
e% *= r%
|
||||
ENDWHILE
|
||||
a%() += l%
|
||||
ENDPROC
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
// Radix sort comparator for 32-bit two's complement integers
|
||||
class radix_test
|
||||
{
|
||||
const int bit; // bit position [0..31] to examine
|
||||
public:
|
||||
radix_test(int offset) : bit(offset) {} // constructor
|
||||
|
||||
bool operator()(int value) const // function call operator
|
||||
{
|
||||
if (bit == 31) // sign bit
|
||||
return value < 0; // negative int to left partition
|
||||
else
|
||||
return !(value & (1 << bit)); // 0 bit to left partition
|
||||
}
|
||||
};
|
||||
|
||||
// Least significant digit radix sort
|
||||
void lsd_radix_sort(int *first, int *last)
|
||||
{
|
||||
for (int lsb = 0; lsb < 32; ++lsb) // least-significant-bit
|
||||
{
|
||||
std::stable_partition(first, last, radix_test(lsb));
|
||||
}
|
||||
}
|
||||
|
||||
// Most significant digit radix sort (recursive)
|
||||
void msd_radix_sort(int *first, int *last, int msb = 31)
|
||||
{
|
||||
if (first != last && msb >= 0)
|
||||
{
|
||||
int *mid = std::partition(first, last, radix_test(msb));
|
||||
msb--; // decrement most-significant-bit
|
||||
msd_radix_sort(first, mid, msb); // sort left partition
|
||||
msd_radix_sort(mid, last, msb); // sort right partition
|
||||
}
|
||||
}
|
||||
|
||||
// test radix_sort
|
||||
int main()
|
||||
{
|
||||
int data[] = { 170, 45, 75, -90, -802, 24, 2, 66 };
|
||||
|
||||
lsd_radix_sort(data, data + 8);
|
||||
// msd_radix_sort(data, data + 8);
|
||||
|
||||
std::copy(data, data + 8, std::ostream_iterator<int>(std::cout, " "));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned uint;
|
||||
#define swap(a, b) { tmp = a; a = b; b = tmp; }
|
||||
#define each(i, x) for (i = 0; i < x; i++)
|
||||
|
||||
/* sort unsigned ints */
|
||||
static void rad_sort_u(uint *from, uint *to, uint bit)
|
||||
{
|
||||
if (!bit || to < from + 1) return;
|
||||
|
||||
uint *ll = from, *rr = to - 1, tmp;
|
||||
while (1) {
|
||||
/* find left most with bit, and right most without bit, swap */
|
||||
while (ll < rr && !(*ll & bit)) ll++;
|
||||
while (ll < rr && (*rr & bit)) rr--;
|
||||
if (ll >= rr) break;
|
||||
swap(*ll, *rr);
|
||||
}
|
||||
|
||||
if (!(bit & *ll) && ll < to) ll++;
|
||||
bit >>= 1;
|
||||
|
||||
rad_sort_u(from, ll, bit);
|
||||
rad_sort_u(ll, to, bit);
|
||||
}
|
||||
|
||||
/* sort signed ints: flip highest bit, sort as unsigned, flip back */
|
||||
static void radix_sort(int *a, const size_t len)
|
||||
{
|
||||
size_t i;
|
||||
uint *x = (uint*) a;
|
||||
|
||||
each(i, len) x[i] ^= INT_MIN;
|
||||
rad_sort_u(x, x + len, INT_MIN);
|
||||
each(i, len) x[i] ^= INT_MIN;
|
||||
}
|
||||
|
||||
static inline void radix_sort_unsigned(uint *a, const size_t len)
|
||||
{
|
||||
rad_sort_u(a, a + len, (uint)INT_MIN);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int len = 16, x[16], i;
|
||||
size_t len = 16, i;
|
||||
each(i, len) x[i] = rand() % 512 - 256;
|
||||
|
||||
radix_sort(x, len);
|
||||
|
||||
each(i, len) printf("%d%c", x[i], i + 1 < len ? ' ' : '\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
import std.stdio, std.math, std.traits, std.range, std.algorithm;
|
||||
|
||||
ElementType!R[] radixSort(size_t N=10, R)(R r)
|
||||
if (hasLength!R && isRandomAccessRange!R &&
|
||||
isIntegral!(ElementType!R)) {
|
||||
alias ElementType!R E;
|
||||
|
||||
static if (isDynamicArray!R)
|
||||
alias r res; // input is array => in place sort
|
||||
else
|
||||
E[] res = r.array(); // input is Range => return a new array
|
||||
|
||||
E absMax = r.map!abs().reduce!max();
|
||||
immutable nPasses = 1 + cast(int)(log(absMax) / log(N));
|
||||
|
||||
foreach (pass; 0 .. nPasses) {
|
||||
auto bucket = new E[][](2 * N - 1, 0);
|
||||
foreach (v; res) {
|
||||
int bIdx = abs(v / (N ^^ pass)) % N;
|
||||
bIdx = (v < 0) ? -bIdx : bIdx;
|
||||
bucket[N + bIdx - 1] ~= v;
|
||||
}
|
||||
res = bucket.join();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto items = [170, 45, 75, -90, 2, 24, -802, 66];
|
||||
items.radixSort().writeln();
|
||||
items.map!q{1 - a}().radixSort().writeln();
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import std.array, std.traits;
|
||||
|
||||
// considered pure for this program
|
||||
extern(C) void* alloca(in size_t length) pure nothrow;
|
||||
|
||||
void radixSort(size_t MAX_ALLOCA=5_000, U)(U[] data)
|
||||
pure nothrow if (isUnsigned!U) {
|
||||
static void radix(in uint byteIndex, in U[] source, U[] dest)
|
||||
pure nothrow {
|
||||
immutable size_t sourceSize = source.length;
|
||||
ubyte* curByte = (cast(ubyte*)source.ptr) + byteIndex;
|
||||
uint[ubyte.max + 1] byteCounter;
|
||||
for (size_t i = 0; i < sourceSize; i++, curByte += U.sizeof)
|
||||
byteCounter[*curByte]++;
|
||||
|
||||
{
|
||||
uint indexStart;
|
||||
foreach (uint i; 0 .. byteCounter.length) {
|
||||
immutable size_t tempCount = byteCounter[i];
|
||||
byteCounter[i] = indexStart;
|
||||
indexStart += tempCount;
|
||||
}
|
||||
}
|
||||
|
||||
curByte = (cast(ubyte*)source.ptr) + byteIndex;
|
||||
for (size_t i = 0; i < sourceSize; i++, curByte += U.sizeof) {
|
||||
uint* countPtr = byteCounter.ptr + *curByte;
|
||||
dest[*countPtr] = source[i];
|
||||
(*countPtr)++;
|
||||
}
|
||||
}
|
||||
|
||||
U[] tempData;
|
||||
if (U.sizeof * data.length <= MAX_ALLOCA) {
|
||||
U* ptr = cast(U*)alloca(data.length * U.sizeof);
|
||||
if (ptr != null)
|
||||
tempData = ptr[0 .. data.length];
|
||||
}
|
||||
if (tempData.empty)
|
||||
tempData = uninitializedArray!(U[])(data.length);
|
||||
|
||||
static if (U.sizeof == 1) {
|
||||
radix(0, data, tempData);
|
||||
data[] = tempData[];
|
||||
} else {
|
||||
for (uint i = 0; i < U.sizeof; i += 2) {
|
||||
radix(i + 0, data, tempData);
|
||||
radix(i + 1, tempData, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
import std.stdio;
|
||||
uint[] items = [170, 45, 75, 4294967206, 2, 24, 4294966494, 66];
|
||||
items.radixSort();
|
||||
writeln(items);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// declarations for word size of data
|
||||
type word int32
|
||||
const wordLen = 4
|
||||
const highBit = -1 << 31
|
||||
|
||||
var data = []word{170, 45, 75, -90, -802, 24, 2, 66}
|
||||
|
||||
func main() {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
ds := make([][]byte, len(data))
|
||||
for i, x := range data {
|
||||
binary.Write(buf, binary.LittleEndian, x^highBit)
|
||||
b := make([]byte, wordLen)
|
||||
buf.Read(b)
|
||||
ds[i] = b
|
||||
}
|
||||
bins := make([][][]byte, 256)
|
||||
for i := 0; i < wordLen; i++ {
|
||||
for _, b := range ds {
|
||||
bins[b[i]] = append(bins[b[i]], b)
|
||||
}
|
||||
j := 0
|
||||
for k, bs := range bins {
|
||||
copy(ds[j:], bs)
|
||||
j += len(bs)
|
||||
bins[k] = bs[:0]
|
||||
}
|
||||
}
|
||||
fmt.Println("original:", data)
|
||||
var w word
|
||||
for i, b := range ds {
|
||||
buf.Write(b)
|
||||
binary.Read(buf, binary.LittleEndian, &w)
|
||||
data[i] = w^highBit
|
||||
}
|
||||
fmt.Println("sorted: ", data)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
def radixSort = { final radixExponent, list ->
|
||||
def fromBuckets = new TreeMap([0:list])
|
||||
def toBuckets = new TreeMap()
|
||||
final radix = 2**radixExponent
|
||||
final mask = radix - 1
|
||||
final radixDigitSize = (int)Math.ceil(64/radixExponent)
|
||||
final digitWidth = radixExponent
|
||||
(0..<radixDigitSize).each { radixDigit ->
|
||||
fromBuckets.values().findAll { it != null }.flatten().each {
|
||||
print '.'
|
||||
long bucketNumber = (long)((((long)it) >>> digitWidth*radixDigit) & mask)
|
||||
toBuckets[bucketNumber] = toBuckets[bucketNumber] ?: []
|
||||
toBuckets[bucketNumber] << it
|
||||
}
|
||||
(fromBuckets, toBuckets) = [toBuckets, fromBuckets]
|
||||
toBuckets.clear()
|
||||
}
|
||||
final overflow = 2**(63 % radixExponent)
|
||||
final pos = {it < overflow}
|
||||
final neg = {it >= overflow}
|
||||
final keys = fromBuckets.keySet()
|
||||
final twosComplIndx = [] + (keys.findAll(neg)) + (keys.findAll(pos))
|
||||
twosComplIndx.collect { fromBuckets[it] }.findAll { it != null }.flatten()
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
println (radixSort(3, [23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4]))
|
||||
println (radixSort(3, [88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1]))
|
||||
println (radixSort(3, [23,-76,-990,580,97,57,350000,Long.MAX_VALUE,89,Long.MIN_VALUE,51,38,95*2**48,92,-24*2**48,46,31*2**32,24,14,12,57,78,4]))
|
||||
println ()
|
||||
println (radixSort(8, [23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4]))
|
||||
println (radixSort(8, [88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1]))
|
||||
println (radixSort(8, [23,-76,-990,580,97,57,350000,Long.MAX_VALUE,89,Long.MIN_VALUE,51,38,95*2**48,92,-24*2**48,46,31*2**32,24,14,12,57,78,4]))
|
||||
println ()
|
||||
println (radixSort(11, [23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4]))
|
||||
println (radixSort(11, [88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1]))
|
||||
println (radixSort(11, [23,-76,-990,580,97,57,350000,Long.MAX_VALUE,89,Long.MIN_VALUE,51,38,95*2**48,92,-24*2**48,46,31*2**32,24,14,12,57,78,4]))
|
||||
println ()
|
||||
println (radixSort(16, [23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4]))
|
||||
println (radixSort(16, [88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1]))
|
||||
println (radixSort(16, [23,-76,-990,580,97,57,350000,Long.MAX_VALUE,89,Long.MIN_VALUE,51,38,95*2**48,92,-24*2**48,46,31*2**32,24,14,12,57,78,4]))
|
||||
println ()
|
||||
println (radixSort(32, [23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4]))
|
||||
println (radixSort(32, [88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1]))
|
||||
println (radixSort(32, [23,-76,-990,580,97,57,350000,Long.MAX_VALUE,89,Long.MIN_VALUE,51,38,95*2**48,92,-24*2**48,46,31*2**32,24,14,12,57,78,4]))
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import Data.Bits (Bits(testBit, bitSize))
|
||||
import Data.List (partition)
|
||||
|
||||
lsdSort :: (Ord a, Bits a) => [a] -> [a]
|
||||
lsdSort = fixSort positiveLsdSort
|
||||
|
||||
msdSort :: (Ord a, Bits a) => [a] -> [a]
|
||||
msdSort = fixSort positiveMsdSort
|
||||
|
||||
-- Fix a sort that puts negative numbers at the end, like positiveLsdSort and positiveMsdSort
|
||||
fixSort sorter list = uncurry (flip (++)) (break (< 0) (sorter list))
|
||||
|
||||
positiveLsdSort :: (Bits a) => [a] -> [a]
|
||||
positiveLsdSort list = foldl step list [0..bitSize (head list)] where
|
||||
step list bit = uncurry (++) (partition (not . flip testBit bit) list)
|
||||
|
||||
positiveMsdSort :: (Bits a) => [a] -> [a]
|
||||
positiveMsdSort list = aux (bitSize (head list) - 1) list where
|
||||
aux _ [] = []
|
||||
aux (-1) list = list
|
||||
aux bit list = aux (bit - 1) lower ++ aux (bit - 1) upper where
|
||||
(lower, upper) = partition (not . flip testBit bit) list
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
radixSortR =: 3 : 0 NB. base radixSort data
|
||||
16 radixSortR y
|
||||
:
|
||||
keys =. x #.^:_1 y NB. compute keys
|
||||
length =. #{.keys
|
||||
extra =. (-length) {."0 buckets =. i.x
|
||||
for_pass. i.-length do.
|
||||
keys =. ; (buckets,pass{"1 keys) <@:}./.extra,keys
|
||||
end.
|
||||
x#.keys NB. restore the data
|
||||
)
|
||||
|
|
@ -0,0 +1 @@
|
|||
radixsort=: (] #~ [: +/ =/) i.@(>./)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
radixsort ?.@#~10
|
||||
4 5 6 6 6 6 6 8 8
|
||||
|
|
@ -0,0 +1 @@
|
|||
rsort=: (] + radixsort@:-) <./
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
rsort _6+?.@#~10
|
||||
_2 _1 0 0 0 0 0 2 2
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
sub radsort (@ints) {
|
||||
my $maxlen = [max] @ints».chars;
|
||||
my @list = @ints».fmt("\%0{$maxlen}d");
|
||||
|
||||
for reverse ^$maxlen -> $r {
|
||||
my @buckets = @list.classify( *.substr($r,1) ).sort: *.key;
|
||||
if !$r and @buckets[0].key eq '-' { @buckets[0].value .= reverse }
|
||||
@list = map *.value.values, @buckets;
|
||||
}
|
||||
@list».Int;
|
||||
}
|
||||
|
||||
.say for radsort (-2_000 .. 2_000).roll(20);
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
(de radixSort (Lst)
|
||||
(let Mask 1
|
||||
(while
|
||||
(let (Pos (list NIL NIL) Neg (list NIL NIL) Flg)
|
||||
(for N Lst
|
||||
(queue
|
||||
(if2 (ge0 N) (bit? Mask N)
|
||||
(cdr Pos) Pos Neg (cdr Neg) )
|
||||
N )
|
||||
(and (>= (abs N) Mask) (on Flg)) )
|
||||
(setq
|
||||
Lst (conc (apply conc Neg) (apply conc Pos))
|
||||
Mask (* 2 Mask) )
|
||||
Flg ) ) )
|
||||
Lst )
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
Structure bucket
|
||||
List i.i()
|
||||
EndStructure
|
||||
|
||||
DataSection
|
||||
;sets specify the size (1 based) followed by each integer
|
||||
set1:
|
||||
Data.i 10 ;size
|
||||
Data.i 1, 3, 8, 9, 0, 0, 8, 7, 1, 6 ;data
|
||||
set2:
|
||||
Data.i 8
|
||||
Data.i 170, 45, 75, 90, 2, 24, 802, 66
|
||||
set3:
|
||||
Data.i 8
|
||||
Data.i 170, 45, 75, 90, 2, 24, -802, -66
|
||||
EndDataSection
|
||||
|
||||
Procedure setIntegerArray(Array x(1), *setPtr)
|
||||
Protected i, count
|
||||
count = PeekI(*setPtr) - 1 ;convert to zero based count
|
||||
*setPtr + SizeOf(Integer) ;move pointer forward to data
|
||||
Dim x(count)
|
||||
For i = 0 To count
|
||||
x(i) = PeekI(*setPtr + i * SizeOf(Integer))
|
||||
Next
|
||||
EndProcedure
|
||||
|
||||
Procedure displayArray(Array x(1))
|
||||
Protected i, Size = ArraySize(x())
|
||||
For i = 0 To Size
|
||||
Print(Str(x(i)))
|
||||
If i < Size: Print(", "): EndIf
|
||||
Next
|
||||
PrintN("")
|
||||
EndProcedure
|
||||
|
||||
Procedure radixSort(Array x(1), Base = 10)
|
||||
Protected count = ArraySize(x())
|
||||
If Base < 1 Or count < 1: ProcedureReturn: EndIf ;exit due to invalid values
|
||||
|
||||
Protected i, pv, digit, digitCount, maxAbs, pass, index
|
||||
;find element with largest number of digits
|
||||
For i = 0 To count
|
||||
If Abs(x(i)) > maxAbs
|
||||
maxAbs = Abs(x(i))
|
||||
EndIf
|
||||
Next
|
||||
|
||||
digitCount = Int(Log(maxAbs)/Log(Base)) + 1
|
||||
|
||||
For pass = 1 To digitCount
|
||||
Dim sortBuckets.bucket(Base * 2 - 1)
|
||||
pv = Pow(Base, pass - 1)
|
||||
|
||||
;place elements in buckets according to the current place-value's digit
|
||||
For index = 0 To count
|
||||
digit = Int(x(index)/pv) % Base + Base
|
||||
AddElement(sortBuckets(digit)\i())
|
||||
sortBuckets(digit)\i() = x(index)
|
||||
Next
|
||||
|
||||
;transfer contents of buckets back into array
|
||||
index = 0
|
||||
For digit = 1 To (Base * 2) - 1
|
||||
ForEach sortBuckets(digit)\i()
|
||||
x(index) = sortBuckets(digit)\i()
|
||||
index + 1
|
||||
Next
|
||||
Next
|
||||
Next
|
||||
EndProcedure
|
||||
|
||||
If OpenConsole()
|
||||
Dim x(0)
|
||||
setIntegerArray(x(), ?set1)
|
||||
radixSort(x()): displayArray(x())
|
||||
|
||||
setIntegerArray(x(), ?set2)
|
||||
radixSort(x()): displayArray(x())
|
||||
|
||||
setIntegerArray(x(), ?set3)
|
||||
radixSort(x(), 2): displayArray(x())
|
||||
|
||||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
|
||||
CloseConsole()
|
||||
EndIf
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#python2.6 <
|
||||
from math import log
|
||||
|
||||
def getDigit(num, base, digit_num):
|
||||
# pulls the selected digit
|
||||
return (num // base ** digit_num) % base
|
||||
|
||||
def makeBlanks(size):
|
||||
# create a list of empty lists to hold the split by digit
|
||||
return [ [] for i in range(size) ]
|
||||
|
||||
def split(a_list, base, digit_num):
|
||||
buckets = makeBlanks(base)
|
||||
for num in a_list:
|
||||
# append the number to the list selected by the digit
|
||||
buckets[getDigit(num, base, digit_num)].append(num)
|
||||
return buckets
|
||||
|
||||
# concatenate the lists back in order for the next step
|
||||
def merge(a_list):
|
||||
new_list = []
|
||||
for sublist in a_list:
|
||||
new_list.extend(sublist)
|
||||
return new_list
|
||||
|
||||
def maxAbs(a_list):
|
||||
# largest abs value element of a list
|
||||
return max(abs(num) for num in a_list)
|
||||
|
||||
def split_by_sign(a_list):
|
||||
# splits values by sign - negative values go to the first bucket,
|
||||
# non-negative ones into the second
|
||||
buckets = [[], []]
|
||||
for num in a_list:
|
||||
if num < 0:
|
||||
buckets[0].append(num)
|
||||
else:
|
||||
buckets[1].append(num)
|
||||
return buckets
|
||||
|
||||
def radixSort(a_list, base):
|
||||
# there are as many passes as there are digits in the longest number
|
||||
passes = int(log(maxAbs(a_list), base) + 1)
|
||||
new_list = list(a_list)
|
||||
for digit_num in range(passes):
|
||||
new_list = merge(split(new_list, base, digit_num))
|
||||
return merge(split_by_sign(new_list))
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*REXX program performs a radix sort on a stemmed integer array. */
|
||||
aList='0 2 3 4 5 5 7 6 6 7 11 7 13 9 8 8 17 8 19 9 10 13 23 9 10 15 9 11',
|
||||
'29 10 31 10 14 19 12 10 37 21 16 11 41 12 43 15 11 25 47 11 14 12',
|
||||
'20 17 53 11 16 13 22 31 59 12 61 33 13 12 18 16 67 21 26 14 71 12',
|
||||
'73 39 13 23 18 18 79 13 12 43 83 14 22 45 32 17 89 13 20 27 34 49',
|
||||
'24 13 97 16 17 14 101 22 103 19 15 55 107 13 109 18 40 15 113 -42'
|
||||
/*excluding -42, the abbreviated list is called the integer log function*/
|
||||
|
||||
mina=word(aList,1); maxa=mina
|
||||
|
||||
do n=1 for words(aList); x=word(aList,n); @.n=x /*list ──► array.*/
|
||||
mina=min(x,mina); maxa=max(x,maxa)
|
||||
width=max(length(abs(mina)),length(maxa))
|
||||
end
|
||||
|
||||
n=words(aList); w=length(n); call radSort n
|
||||
|
||||
do j=1 for n
|
||||
say 'item' right(j,w) "after the radix sort:" right(@.j,width+1)
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*───────────────────────────────────RADSORT subroutine─────────────────*/
|
||||
radSort: procedure expose @. width; parse arg size; mote=c2d(' '); #=1
|
||||
!.#._b=1
|
||||
!.#._i=1
|
||||
!.#._n=size; do i=1 for size; y=@.i; @.i=right(abs(y),width,0)
|
||||
if y<0 then @.i='-'@.i
|
||||
end /*i*/
|
||||
/*══════════════════════════════════════where the rubber meets the road.*/
|
||||
do while #\==0; ctr.=0; L='ffff'x; low=!.#._b; n=!.#._n; radi=!.#._i; H=
|
||||
#=#-1
|
||||
do j=low for n; parse var @.j =(radi) _ +1; ctr._=ctr._+1
|
||||
if ctr._==1 then if _\=='' then do
|
||||
if _<<L then L=_
|
||||
if _>>H then H=_
|
||||
end
|
||||
end /*j*/
|
||||
|
||||
if L>>H then iterate
|
||||
_=
|
||||
if L==H then if ctr._==0 then do; #=#+1; !.#._b=low
|
||||
!.#._n=n
|
||||
!.#._i=radi+1; iterate
|
||||
end
|
||||
|
||||
L=c2d(L); H=c2d(H); ?=ctr._+low; top._=?; ts=mote; max=L
|
||||
|
||||
do k=L to H; _=d2c(k,1); cen=ctr._
|
||||
if cen>ts then parse value cen k with ts max
|
||||
?=?+cen; top._=?
|
||||
end /*k*/
|
||||
pivot=low
|
||||
|
||||
do while pivot<low+n; it=@.pivot
|
||||
do forever
|
||||
parse var it =(radi) _ +1; cen=top._-1; if pivot>=cen then leave
|
||||
top._=cen; ?=@.cen; @.cen=it; it=?
|
||||
end /*forever*/
|
||||
top._=pivot; @.pivot=it; pivot=pivot+ctr._
|
||||
end /*while pivot<low+n*/
|
||||
|
||||
i=max
|
||||
|
||||
do until i==max; _=d2c(i,1); i=i+1; if i>H then i=L; d=ctr._
|
||||
if d<=mote then do; if d>1 then call .radSortP top._,d; iterate; end
|
||||
#=#+1; !.#._b=top._
|
||||
!.#._n=d
|
||||
!.#._i=radi+1
|
||||
end /*until i==max*/
|
||||
end /*while #\==0 */
|
||||
/*═════════════════════════════════════we're done with the heavy lifting*/
|
||||
|
||||
do i=1 for size; @.i=@.i+0; end /*i*/
|
||||
return
|
||||
/*───────────────────────────────────.radSortP subroutine───────────────*/
|
||||
.radSortP: parse arg bbb,nnn
|
||||
do k=bbb+1 for nnn-1; q=@.k
|
||||
do j=k-1 by -1 to bbb while q<<@.j; jp=j+1; @.jp=@.j; end
|
||||
jp=j+1; @.jp=q
|
||||
end /*k*/
|
||||
return
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
class Array
|
||||
def radix_sort(base=10)
|
||||
ary = dup
|
||||
rounds = (Math.log(self.max.abs)/Math.log(base)).ceil
|
||||
rounds.times do |i|
|
||||
buckets = Hash.new {|h,k| h[k] = []}
|
||||
ary.each do |n|
|
||||
digit = (n/base**i) % base
|
||||
digit = digit + base unless n<0
|
||||
buckets[digit] << n
|
||||
end
|
||||
ary = buckets.values_at(*(0..2*base)).compact.flatten
|
||||
p [i, ary] if $DEBUG
|
||||
end
|
||||
ary
|
||||
end
|
||||
def radix_sort!(base=10)
|
||||
replace radix_sort(base)
|
||||
end
|
||||
end
|
||||
|
||||
p [1, 3, 8, 9, 0, 0, 8, 7, 1, 6].radix_sort
|
||||
p [170, 45, 75, 90, 2, 24, 802, 66].radix_sort
|
||||
p [170, 45, 75, 90, 2, 24, -802, -66].radix_sort
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package require Tcl 8.5
|
||||
proc splitByRadix {lst base power} {
|
||||
# create a list of empty lists to hold the split by digit
|
||||
set out [lrepeat [expr {$base*2}] {}]
|
||||
foreach item $lst {
|
||||
# pulls the selected digit
|
||||
set digit [expr {($item / $base ** $power) % $base + $base * ($item >= 0)}]
|
||||
# append the number to the list selected by the digit
|
||||
lset out $digit [list {*}[lindex $out $digit] $item]
|
||||
}
|
||||
return $out
|
||||
}
|
||||
|
||||
# largest abs value element of a list
|
||||
proc tcl::mathfunc::maxabs {lst} {
|
||||
set max [abs [lindex $lst 0]]
|
||||
for {set i 1} {$i < [llength $lst]} {incr i} {
|
||||
set v [abs [lindex $lst $i]]
|
||||
if {$max < $v} {set max $v}
|
||||
}
|
||||
return $max
|
||||
}
|
||||
|
||||
proc radixSort {lst {base 10}} {
|
||||
# there are as many passes as there are digits in the longest number
|
||||
set passes [expr {int(log(maxabs($lst))/log($base) + 1)}]
|
||||
# For each pass...
|
||||
for {set pass 0} {$pass < $passes} {incr pass} {
|
||||
# Split by radix, then merge back into the list
|
||||
set lst [concat {*}[splitByRadix $lst $base $pass]]
|
||||
}
|
||||
return $lst
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
puts [radixSort {1 3 8 9 0 0 8 7 1 6}]
|
||||
puts [radixSort {170 45 75 90 2 24 802 66}]
|
||||
puts [radixSort {170 45 75 90 2 24 -802 -66}]
|
||||
Loading…
Add table
Add a link
Reference in a new issue