Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
|
|
@ -1,60 +1,68 @@
|
|||
class
|
||||
MERGE_SORT [G -> COMPARABLE]
|
||||
|
||||
create
|
||||
sort
|
||||
|
||||
feature
|
||||
sort(ar: ARRAY[G])
|
||||
-- sort array ar with mergesort and save it in sorted_array
|
||||
require
|
||||
ar_not_empty: ar.is_empty= FALSE
|
||||
do
|
||||
|
||||
sort (ar: ARRAY [G])
|
||||
-- Sorted array in ascending order.
|
||||
require
|
||||
ar_not_empty: not ar.is_empty
|
||||
do
|
||||
create sorted_array.make_empty
|
||||
mergesort(ar, 1, ar.count)
|
||||
sorted_array:= ar
|
||||
ensure
|
||||
sorted_array_not_empty: sorted_array.is_empty = FALSE
|
||||
sorted: is_sorted(sorted_array, 1, sorted_array.count)= TRUE
|
||||
end
|
||||
sorted_array: ARRAY[G]
|
||||
mergesort (ar, 1, ar.count)
|
||||
sorted_array := ar
|
||||
ensure
|
||||
sorted_array_not_empty: not sorted_array.is_empty
|
||||
sorted: is_sorted (sorted_array, 1, sorted_array.count)
|
||||
end
|
||||
|
||||
sorted_array: ARRAY [G]
|
||||
|
||||
feature {NONE}
|
||||
mergesort(ar:ARRAY[G]; l,r:INTEGER)
|
||||
|
||||
mergesort (ar: ARRAY [G]; l, r: INTEGER)
|
||||
-- Sorting part of mergesort.
|
||||
local
|
||||
m: INTEGER
|
||||
do
|
||||
if l<r then
|
||||
m := (l+r)//2
|
||||
mergesort(ar,l, m)
|
||||
mergesort(ar,m+1,r)
|
||||
merge(ar,l,m,r)
|
||||
if l < r then
|
||||
m := (l + r) // 2
|
||||
mergesort (ar, l, m)
|
||||
mergesort (ar, m + 1, r)
|
||||
merge (ar, l, m, r)
|
||||
end
|
||||
end
|
||||
|
||||
merge(ar:ARRAY[G]; l,m,r: INTEGER)
|
||||
merge (ar: ARRAY [G]; l, m, r: INTEGER)
|
||||
-- Merge part of mergesort.
|
||||
require
|
||||
positive_index_l: l>=1
|
||||
positive_index_m: m>=1
|
||||
positive_index_r: r>=1
|
||||
ar_not_empty: ar.is_empty= FALSE
|
||||
positive_index_l: l >= 1
|
||||
positive_index_m: m >= 1
|
||||
positive_index_r: r >= 1
|
||||
ar_not_empty: not ar.is_empty
|
||||
local
|
||||
merged: ARRAY[G]
|
||||
h,i,j,k: INTEGER
|
||||
merged: ARRAY [G]
|
||||
h, i, j, k: INTEGER
|
||||
do
|
||||
i := l
|
||||
j := m+1
|
||||
j := m + 1
|
||||
k := l
|
||||
create merged.make_empty
|
||||
create merged.make_filled (ar [1], 1, ar.count)
|
||||
from
|
||||
until
|
||||
i > m or j > r
|
||||
loop
|
||||
if ar.item (i) <= ar.item (j) then
|
||||
merged.force(ar.item(i),k)
|
||||
i := i +1
|
||||
merged.force (ar.item (i), k)
|
||||
i := i + 1
|
||||
elseif ar.item (i) > ar.item (j) then
|
||||
merged.force(ar.item(j),k)
|
||||
j := j+1
|
||||
merged.force (ar.item (j), k)
|
||||
j := j + 1
|
||||
end
|
||||
k := k+1
|
||||
k := k + 1
|
||||
end
|
||||
if i > m then
|
||||
from
|
||||
|
|
@ -62,8 +70,8 @@ feature {NONE}
|
|||
until
|
||||
h > r
|
||||
loop
|
||||
merged.force(ar.item(h),k+h-j)
|
||||
h := h+1
|
||||
merged.force (ar.item (h), k + h - j)
|
||||
h := h + 1
|
||||
end
|
||||
elseif j > m then
|
||||
from
|
||||
|
|
@ -71,8 +79,8 @@ feature {NONE}
|
|||
until
|
||||
h > m
|
||||
loop
|
||||
merged.force(ar.item(h),k+h-i)
|
||||
h := h+1
|
||||
merged.force (ar.item (h), k + h - i)
|
||||
h := h + 1
|
||||
end
|
||||
end
|
||||
from
|
||||
|
|
@ -81,37 +89,32 @@ feature {NONE}
|
|||
h > r
|
||||
loop
|
||||
ar.item (h) := merged.item (h)
|
||||
h := h+1
|
||||
h := h + 1
|
||||
end
|
||||
ensure
|
||||
is_partially_sorted: is_sorted(ar, l,r)= TRUE
|
||||
ensure
|
||||
is_partially_sorted: is_sorted (ar, l, r)
|
||||
end
|
||||
|
||||
is_sorted(ar: ARRAY[G];l, r: INTEGER): BOOLEAN
|
||||
--- feature is not required for mergesort but is used for contracts
|
||||
is_sorted (ar: ARRAY [G]; l, r: INTEGER): BOOLEAN
|
||||
-- Is 'ar' sorted in ascending order?
|
||||
require
|
||||
ar_not_empty: ar.is_empty= FALSE
|
||||
ar_not_empty: not ar.is_empty
|
||||
l_in_range: l >= 1
|
||||
r_in_range: r <= ar.count
|
||||
local
|
||||
smaller : BOOLEAN
|
||||
i: INTEGER
|
||||
do
|
||||
smaller:= TRUE
|
||||
Result := True
|
||||
from
|
||||
i:= l
|
||||
i := l
|
||||
until
|
||||
i=r
|
||||
i = r
|
||||
loop
|
||||
if ar[i]> ar[i+1] then
|
||||
smaller:= FALSE
|
||||
if ar [i] > ar [i + 1] then
|
||||
Result := False
|
||||
end
|
||||
i:= i+1
|
||||
end
|
||||
if smaller = TRUE then
|
||||
RESULT := TRUE
|
||||
else
|
||||
RESULT:= FALSE
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,19 +1,31 @@
|
|||
class
|
||||
APPLICATION
|
||||
inherit
|
||||
ARGUMENTS
|
||||
|
||||
create
|
||||
make
|
||||
feature
|
||||
make
|
||||
do
|
||||
test:= <<2,5,66,-2, 0, 7>>
|
||||
io.put_string ("unsorted"+ "%N")
|
||||
across test as ar loop io.put_string (ar.item.out + "%T") end
|
||||
io.put_string ("%N"+"sorted"+ "%N")
|
||||
create merge.sort (test)
|
||||
across merge.sorted_array as ar loop io.put_string (ar.item.out + "%T") end
|
||||
end
|
||||
test: ARRAY[INTEGER]
|
||||
merge: MERGE_SORT[INTEGER]
|
||||
|
||||
feature
|
||||
|
||||
make
|
||||
do
|
||||
test := <<2, 5, 66, -2, 0, 7>>
|
||||
io.put_string ("unsorted" + "%N")
|
||||
across
|
||||
test as ar
|
||||
loop
|
||||
io.put_string (ar.item.out + "%T")
|
||||
end
|
||||
io.put_string ("%N" + "sorted" + "%N")
|
||||
create merge.sort (test)
|
||||
across
|
||||
merge.sorted_array as ar
|
||||
loop
|
||||
io.put_string (ar.item.out + "%T")
|
||||
end
|
||||
end
|
||||
|
||||
test: ARRAY [INTEGER]
|
||||
|
||||
merge: MERGE_SORT [INTEGER]
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
defmodule Sort do
|
||||
def merge_sort(list) when length(list) <= 1, do: list
|
||||
def merge_sort(list) do
|
||||
{left, right} = Enum.split(list, div(length(list), 2))
|
||||
:lists.merge( merge_sort(left), merge_sort(right))
|
||||
end
|
||||
end
|
||||
|
|
@ -1,21 +1,31 @@
|
|||
function merge(left, right, arr) {
|
||||
var a = 0;
|
||||
while (left.length && right.length)
|
||||
arr[a++] = right[0] < left[0] ? right.shift() : left.shift();
|
||||
while (left.length) arr[a++] = left.shift();
|
||||
while (right.length) arr[a++] = right.shift();
|
||||
var a = 0;
|
||||
|
||||
while (left.length && right.length) {
|
||||
arr[a++] = (right[0] < left[0]) ? right.shift() : left.shift();
|
||||
}
|
||||
while (left.length) {
|
||||
arr[a++] = left.shift();
|
||||
}
|
||||
while (right.length) {
|
||||
arr[a++] = right.shift();
|
||||
}
|
||||
}
|
||||
|
||||
function mSort(arr, tmp, len) {
|
||||
if (len == 1) return;
|
||||
var m = Math.floor(len / 2),
|
||||
tmp_l = tmp.slice(0, m),
|
||||
tmp_r = tmp.slice(m);
|
||||
mSort(tmp_l, arr.slice(0, m), m);
|
||||
mSort(tmp_r, arr.slice(m), len - m);
|
||||
merge(tmp_l, tmp_r, arr);
|
||||
if (len === 1) { return; }
|
||||
|
||||
var m = Math.floor(len / 2),
|
||||
tmp_l = tmp.slice(0, m),
|
||||
tmp_r = tmp.slice(m);
|
||||
|
||||
mSort(tmp_l, arr.slice(0, m), m);
|
||||
mSort(tmp_r, arr.slice(m), len - m);
|
||||
merge(tmp_l, tmp_r, arr);
|
||||
}
|
||||
|
||||
function merge_sort(arr) {
|
||||
mSort(arr, arr.slice(), arr.length);
|
||||
mSort(arr, arr.slice(), arr.length);
|
||||
}
|
||||
|
||||
var arr = [1, 5, 2, 7, 3, 9, 4, 6, 8];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
function mergesort!(A::AbstractVector)
|
||||
if length(A) <= 1
|
||||
return A
|
||||
end
|
||||
middle = div(length(A), 2)
|
||||
left = mergesort(A[1:middle])
|
||||
right = mergesort(A[middle + 1:end])
|
||||
result = Array(eltype(left), length(left) + length(right))
|
||||
idx = 1
|
||||
@inbounds while !isempty(left) && !isempty(right)
|
||||
if left[1] <= right[1]
|
||||
result[idx] = left[1]
|
||||
left = left[2:end]
|
||||
else
|
||||
result[idx] = right[1]
|
||||
right = right[2:end]
|
||||
end
|
||||
idx += 1
|
||||
end
|
||||
@inbounds while !isempty(left)
|
||||
result[idx] = left[1]
|
||||
left = left[2:end]
|
||||
idx += 1
|
||||
end
|
||||
@inbounds while !isempty(right)
|
||||
result[idx] = right[1]
|
||||
right = right[2:end]
|
||||
idx += 1
|
||||
end
|
||||
for i=1:length(A)
|
||||
A[i] = result[i]
|
||||
end
|
||||
return A
|
||||
end
|
||||
|
||||
function mergesort(A::AbstractVector)
|
||||
return mergesort!(copy(A))
|
||||
end
|
||||
|
||||
A = randcycle(10)
|
||||
println("unsorted: ", A)
|
||||
println("sorted: ", mergesort(A))
|
||||
|
|
@ -8,11 +8,13 @@ uses
|
|||
sysutils; //for timing
|
||||
type
|
||||
tDataElem = record
|
||||
myText : AnsiString;
|
||||
myX,
|
||||
myY : double;
|
||||
myTag,
|
||||
myOrgIdx : LongInt;
|
||||
end;
|
||||
|
||||
tpDataElem = ^tDataElem;
|
||||
tData = array of tDataElem;
|
||||
|
||||
|
|
@ -36,6 +38,7 @@ begin
|
|||
Sortdata[i] := @D[i];
|
||||
with D[i] do
|
||||
Begin
|
||||
myText := Format('_%.9d',[random(cnt)+1]);
|
||||
myX := Random*k;
|
||||
myY := Random*k;
|
||||
myTag := Random(k);
|
||||
|
|
@ -51,9 +54,32 @@ begin
|
|||
Setlength(D,0);
|
||||
end;
|
||||
|
||||
function CompLowercase(A,B:tpDataElem):integer;
|
||||
var
|
||||
lcA,lcB: String;
|
||||
Begin
|
||||
lcA := lowercase(A^.myText);
|
||||
lcB := lowercase(B^.myText);
|
||||
result := ORD(lcA > lcB)-ORD(lcA < lcB);
|
||||
end;
|
||||
|
||||
function myCompText(A,B:tpDataElem):integer;
|
||||
{sort an array (or list) of strings in order of descending length,
|
||||
and in ascending lexicographic order for strings of equal length.}
|
||||
var
|
||||
lA,lB:integer;
|
||||
|
||||
Begin
|
||||
lA := Length(A^.myText);
|
||||
lB := Length(B^.myText);
|
||||
result := ORD(lA<lB)-ORD(lA>lB);
|
||||
IF result = 0 then
|
||||
result := CompLowercase(A,B);
|
||||
end;
|
||||
|
||||
function myCompX(A,B:tpDataElem):integer;
|
||||
//same as sign without jumps in assembler code
|
||||
Begin
|
||||
begin
|
||||
result := ORD(A^.myX > B^.myX)-ORD(A^.myX < B^.myX);
|
||||
end;
|
||||
|
||||
|
|
@ -145,10 +171,15 @@ Begin
|
|||
randomize;
|
||||
InitData(Data,1*1000*1000);
|
||||
|
||||
T0 := Time;
|
||||
mergesort(Low(SortData),High(SortData),SortData,@myCompText);
|
||||
T1 := Time;
|
||||
Writeln('myText ',FormatDateTime('NN:SS.ZZZ',T1-T0));
|
||||
// For i := 0 to High(Data) do Write(SortData[i].myText); writeln;
|
||||
T0 := Time;
|
||||
mergesort(Low(SortData),High(SortData),SortData,@myCompX);
|
||||
T1 := Time;
|
||||
Writeln('myX ',FormatDateTime('NN:SS.ZZZ',T1-T0));
|
||||
Writeln('myX ',FormatDateTime('NN:SS.ZZZ',T1-T0));
|
||||
//check
|
||||
For i := 1 to High(Data) do
|
||||
IF myCompX(SortData[i-1],SortData[i]) = 1 then
|
||||
|
|
@ -157,7 +188,7 @@ Begin
|
|||
T0 := Time;
|
||||
mergesort(Low(SortData),High(SortData),SortData,@myCompY);
|
||||
T1 := Time;
|
||||
Writeln('myY ',FormatDateTime('NN:SS.ZZZ',T1-T0));
|
||||
Writeln('myY ',FormatDateTime('NN:SS.ZZZ',T1-T0));
|
||||
|
||||
T0 := Time;
|
||||
mergesort(Low(SortData),High(SortData),SortData,@myCompTag);
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ sub merge_sort ( @a ) {
|
|||
return @a if @a <= 1;
|
||||
|
||||
my $m = @a.elems div 2;
|
||||
my @l = merge_sort @a[ 0 ..^ $m ];
|
||||
my @r = merge_sort @a[ $m ..^ @a ];
|
||||
my @l = flat merge_sort @a[ 0 ..^ $m ];
|
||||
my @r = flat merge_sort @a[ $m ..^ @a ];
|
||||
|
||||
return @l, @r if @l[*-1] !after @r[0];
|
||||
return gather {
|
||||
return flat @l, @r if @l[*-1] !after @r[0];
|
||||
return flat gather {
|
||||
take @l[0] before @r[0] ?? @l.shift !! @r.shift
|
||||
while @l and @r;
|
||||
take @l, @r;
|
||||
|
|
|
|||
|
|
@ -1,105 +1,36 @@
|
|||
Function Merge-Array( [Object[]] $lhs, [Object[]] $rhs )
|
||||
function MergeSort([object[]] $SortInput)
|
||||
{
|
||||
$result = @()
|
||||
$lhsl = $lhs.length
|
||||
$rhsl = $rhs.length
|
||||
if( $lhsl -gt 0 )
|
||||
# The base case exits for minimal lists that are sorted by definition
|
||||
if ($SortInput.Length -le 1) {return $SortInput}
|
||||
|
||||
# Divide and conquer
|
||||
[int] $midPoint = $SortInput.Length/2
|
||||
# The @() operators ensure a single result remains typed as an array
|
||||
[object[]] $left = @(MergeSort @($SortInput[0..($midPoint-1)]))
|
||||
[object[]] $right = @(MergeSort @($SortInput[$midPoint..($SortInput.Length-1)]))
|
||||
|
||||
# Merge
|
||||
[object[]] $result = @()
|
||||
while (($left.Length -gt 0) -and ($right.Length -gt 0))
|
||||
{
|
||||
if( $rhsl -gt 0 )
|
||||
if ($left[0] -lt $right[0])
|
||||
{
|
||||
$i = 0
|
||||
for( $j = 0; ( $i -lt $lhsl ) -and ( $j -lt $rhsl ); )
|
||||
{
|
||||
if( $lhs[ $i ] -le $rhs[ $j ] )
|
||||
{
|
||||
$result += $lhs[ $i ]
|
||||
[void] ( $i++ )
|
||||
} else {
|
||||
$result += $rhs[ $j ]
|
||||
[void] ( $j++ )
|
||||
}
|
||||
}
|
||||
if( $i -lt $lhsl )
|
||||
{
|
||||
$result += $lhs[ $i..( $lhsl - 1 ) ]
|
||||
}
|
||||
if( $j -lt $rhsl )
|
||||
{
|
||||
$result += $rhs[ $j..( $rhsl - 1 ) ]
|
||||
}
|
||||
} else {
|
||||
for( $i = 0; $i -lt $lhsl; $i++ )
|
||||
{
|
||||
if( $rhs -le $lhs[ $i ] )
|
||||
{
|
||||
$result += $rhs
|
||||
break
|
||||
}
|
||||
$result += $lhs[ $i ]
|
||||
}
|
||||
if( $i -lt $lhsl )
|
||||
{
|
||||
$result += $lhs[ $i..( $lhsl - 1 ) ]
|
||||
}
|
||||
$result += $left[0]
|
||||
# Use an if/else rather than accessing the array range as $array[1..0]
|
||||
if ($left.Length -gt 1){$left = $left[1..$($left.Length-1)]}
|
||||
else {$left = @()}
|
||||
}
|
||||
} else {
|
||||
if( $rhsl -gt 0 )
|
||||
else
|
||||
{
|
||||
for( $i = 0; $i -lt $rhsl; $i++ )
|
||||
{
|
||||
if( $lhs -le $rhs[ $i ] )
|
||||
{
|
||||
$result += $lhs
|
||||
break
|
||||
}
|
||||
$result += $rhs[ $i ]
|
||||
}
|
||||
if( $i -lt $rhsl )
|
||||
{
|
||||
$result += $rhs[ $i..( $rhsl - 1 ) ]
|
||||
}
|
||||
} else {
|
||||
if( $lhs -lt $rhs )
|
||||
{
|
||||
$result += $lhs
|
||||
$result += $rhs
|
||||
} else {
|
||||
$result += $rhs
|
||||
$result += $lhs
|
||||
}
|
||||
$result += $right[0]
|
||||
# Without the if/else, $array[1..0] would return the whole array when $array.Length == 1
|
||||
if ($right.Length -gt 1){$right = $right[1..$($right.Length-1)]}
|
||||
else {$right = @()}
|
||||
}
|
||||
}
|
||||
$result
|
||||
|
||||
# If we get here, either $left or $right is an empty array (or both are empty!). Since the
|
||||
# rest of the unmerged array is already sorted, we can simply string together what we have.
|
||||
# This line outputs the concatenated result. An explicit 'return' statement is not needed.
|
||||
$result + $left + $right
|
||||
}
|
||||
|
||||
Function MergeSort( [Object[]] $data )
|
||||
{
|
||||
$datal = $data.length - 1
|
||||
if( $datal -gt 0 )
|
||||
{
|
||||
$middle = [Math]::Floor( $datal / 2 )
|
||||
$left = @()
|
||||
$left += MergeSort $data[ 0..$middle ]
|
||||
$right = @()
|
||||
$right += MergeSort $data[ ( $middle + 1 )..$datal ]
|
||||
if( $left[ -1 ] -le $right[ 0 ] )
|
||||
{
|
||||
$result = @()
|
||||
$result += $left
|
||||
$result += $right
|
||||
$result
|
||||
} elseif( $right[ -1 ] -le $left[ 0 ] )
|
||||
{
|
||||
$result = @()
|
||||
$result += $right
|
||||
$result += $left
|
||||
$result
|
||||
} else {
|
||||
Merge-Array $left $right
|
||||
}
|
||||
} else {
|
||||
$data
|
||||
}
|
||||
}
|
||||
|
||||
$l = 100; MergeSort ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( 0, $l - 1 ) } )
|
||||
|
|
|
|||
|
|
@ -2,22 +2,15 @@ def merge_sort(m)
|
|||
return m if m.length <= 1
|
||||
|
||||
middle = m.length / 2
|
||||
left = m[0..middle - 1]
|
||||
right = m[middle..-1]
|
||||
|
||||
left = merge_sort(left)
|
||||
right = merge_sort(right)
|
||||
left = merge_sort(m[0...middle])
|
||||
right = merge_sort(m[middle..-1])
|
||||
merge(left, right)
|
||||
end
|
||||
|
||||
def merge(left, right)
|
||||
result = []
|
||||
until left.empty? || right.empty?
|
||||
if left.first <= right.first
|
||||
result << left.shift
|
||||
else
|
||||
result << right.shift
|
||||
end
|
||||
result << (left.first<=right.first ? left.shift : right.shift)
|
||||
end
|
||||
result + left + right
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
class Array
|
||||
def mergesort(&comparitor)
|
||||
return self if length <= 1
|
||||
comparitor ||= lambda {|a, b| a <=> b}
|
||||
comparitor ||= proc{|a, b| a <=> b}
|
||||
middle = length / 2
|
||||
left = self[0..middle - 1].mergesort(&comparitor)
|
||||
left = self[0...middle].mergesort(&comparitor)
|
||||
right = self[middle..-1].mergesort(&comparitor)
|
||||
merge(left, right, comparitor)
|
||||
end
|
||||
|
|
@ -28,5 +28,7 @@ p ary.mergesort # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|||
p ary.mergesort {|a, b| b <=> a} # => [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
|
||||
ary = [["UK", "London"], ["US", "New York"], ["US", "Birmingham"], ["UK", "Birmingham"]]
|
||||
p ary.mergesort
|
||||
# => [["UK", "Birmingham"], ["UK", "London"], ["US", "Birmingham"], ["US", "New York"]]
|
||||
p ary.mergesort {|a, b| a[1] <=> b[1]}
|
||||
# => [["US", "Birmingham"], ["UK", "Birmingham"], ["UK", "London"], ["US", "New York"]]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue