Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,6 +1,12 @@
|
|||
{{Sorting Algorithm}}[[Category:Recursion]]The '''merge sort''' is a recursive sort of order n*log(n). It is notable for having a worst case and average complexity of ''O(n*log(n))'', and a best case complexity of ''O(n)'' (for pre-sorted input). The basic idea is to split the collection into smaller groups by halving it until the groups only have one element or no elements (which are both entirely sorted groups). Then merge the groups back together so that their elements are in order. This is how the algorithm gets its "divide and conquer" description.
|
||||
{{Sorting Algorithm}}[[Category:Recursion]]The '''merge sort''' is a recursive sort of order n*log(n).
|
||||
It is notable for having a worst case and average complexity of ''O(n*log(n))'', and a best case complexity of ''O(n)'' (for pre-sorted input).
|
||||
The basic idea is to split the collection into smaller groups by halving it until the groups only have one element or no elements (which are both entirely sorted groups).
|
||||
Then merge the groups back together so that their elements are in order.
|
||||
This is how the algorithm gets its "divide and conquer" description.
|
||||
|
||||
Write a function to sort a collection of integers using the merge sort. The merge sort algorithm comes in two parts: a sort function and a merge function. The functions in pseudocode look like this:
|
||||
Write a function to sort a collection of integers using the merge sort.
|
||||
The merge sort algorithm comes in two parts: a sort function and a merge function.
|
||||
The functions in pseudocode look like this:
|
||||
'''function''' ''mergesort''(m)
|
||||
'''var''' list left, right, result
|
||||
'''if''' length(m) ≤ 1
|
||||
|
|
@ -35,3 +41,5 @@ Write a function to sort a collection of integers using the merge sort. The merg
|
|||
'''return''' result
|
||||
|
||||
For more information see [[wp:Merge_sort|Wikipedia]]
|
||||
|
||||
Note: better performance can be expected if, rather than recursing until length(m) ≤ 1, an insertion sort is used for length(m) smaller than some threshold larger than 1. However, this complicates example code, so is not shown here.
|
||||
|
|
|
|||
|
|
@ -1,102 +1,38 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LEN 20
|
||||
#define MAXEL 100
|
||||
|
||||
void merge(int * list, int left_start, int left_end, int right_start, int right_end)
|
||||
{
|
||||
/* calculate temporary list sizes */
|
||||
int left_length = left_end - left_start;
|
||||
int right_length = right_end - right_start;
|
||||
|
||||
/* declare temporary lists */
|
||||
int left_half[left_length];
|
||||
int right_half[right_length];
|
||||
|
||||
int r = 0; /* right_half index */
|
||||
int l = 0; /* left_half index */
|
||||
int i = 0; /* list index */
|
||||
|
||||
/* copy left half of list into left_half */
|
||||
for (i = left_start; i < left_end; i++, l++)
|
||||
{
|
||||
left_half[l] = list[i];
|
||||
}
|
||||
|
||||
/* copy right half of list into right_half */
|
||||
for (i = right_start; i < right_end; i++, r++)
|
||||
{
|
||||
right_half[r] = list[i];
|
||||
}
|
||||
|
||||
/* merge left_half and right_half back into list */
|
||||
for ( i = left_start, r = 0, l = 0; l < left_length && r < right_length; i++)
|
||||
{
|
||||
if ( left_half[l] < right_half[r] ) { list[i] = left_half[l++]; }
|
||||
else { list[i] = right_half[r++]; }
|
||||
}
|
||||
|
||||
/* Copy over leftovers of whichever temporary list hasn't finished */
|
||||
for ( ; l < left_length; i++, l++) { list[i] = left_half[l]; }
|
||||
for ( ; r < right_length; i++, r++) { list[i] = right_half[r]; }
|
||||
void merge (int *a, int n, int m) {
|
||||
int i, j, k;
|
||||
int *x = malloc(n * sizeof (int));
|
||||
for (i = 0, j = m, k = 0; k < n; k++) {
|
||||
x[k] = j == n ? a[i++]
|
||||
: i == m ? a[j++]
|
||||
: a[j] < a[i] ? a[j++]
|
||||
: a[i++];
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
a[i] = x[i];
|
||||
}
|
||||
free(x);
|
||||
}
|
||||
|
||||
void mergesort_r(int left, int right, int * list)
|
||||
{
|
||||
/* Base case, the list can be no simpiler */
|
||||
if (right - left <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* set up bounds to slice array into */
|
||||
int left_start = left;
|
||||
int left_end = (left+right)/2;
|
||||
int right_start = left_end;
|
||||
int right_end = right;
|
||||
|
||||
/* sort left half */
|
||||
mergesort_r( left_start, left_end, list);
|
||||
/* sort right half */
|
||||
mergesort_r( right_start, right_end, list);
|
||||
|
||||
/* merge sorted halves back together */
|
||||
merge(list, left_start, left_end, right_start, right_end);
|
||||
void merge_sort (int *a, int n) {
|
||||
if (n < 2)
|
||||
return;
|
||||
int m = n / 2;
|
||||
merge_sort(a, m);
|
||||
merge_sort(a + m, n - m);
|
||||
merge(a, n, m);
|
||||
}
|
||||
|
||||
void mergesort(int * list, int length)
|
||||
{
|
||||
mergesort_r(0, length, list);
|
||||
}
|
||||
|
||||
void print_list(int * list, int len)
|
||||
{
|
||||
/* Print all the ints of a list in brackets followed by a newline */
|
||||
int i;
|
||||
|
||||
printf("[ ");
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
printf("%d ", list[i]);
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
/* Set up the list */
|
||||
int list[LEN], i;
|
||||
for (i = 0; i < LEN; i++) { list[i] = rand() % MAXEL; }
|
||||
|
||||
/* Do merge sort and print before/after */
|
||||
printf("Before sort: ");
|
||||
print_list(list, LEN);
|
||||
|
||||
mergesort(list, LEN);
|
||||
|
||||
printf("After sort: ");
|
||||
print_list(list, LEN);
|
||||
|
||||
return 0;
|
||||
int main () {
|
||||
int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};
|
||||
int n = sizeof a / sizeof a[0];
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
|
||||
merge_sort(a, n);
|
||||
for (i = 0; i < n; i++)
|
||||
printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import std.stdio, std.algorithm, std.array, std.range;
|
||||
|
||||
T[] mergeSorted(T)(in T[] D) /*pure nothrow*/ {
|
||||
T[] mergeSorted(T)(in T[] D) /*pure nothrow @safe*/ {
|
||||
if (D.length < 2)
|
||||
return D.dup;
|
||||
return [D[0 .. $ / 2].mergeSorted, D[$ / 2 .. $].mergeSorted]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
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
|
||||
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]
|
||||
feature {NONE}
|
||||
mergesort(ar:ARRAY[G]; l,r:INTEGER)
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
merge(ar:ARRAY[G]; l,m,r: INTEGER)
|
||||
require
|
||||
positive_index_l: l>=1
|
||||
positive_index_m: m>=1
|
||||
positive_index_r: r>=1
|
||||
ar_not_empty: ar.is_empty= FALSE
|
||||
local
|
||||
merged: ARRAY[G]
|
||||
h,i,j,k: INTEGER
|
||||
do
|
||||
i := l
|
||||
j := m+1
|
||||
k := l
|
||||
create merged.make_empty
|
||||
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
|
||||
elseif ar.item (i) > ar.item (j) then
|
||||
merged.force(ar.item(j),k)
|
||||
j := j+1
|
||||
end
|
||||
k := k+1
|
||||
end
|
||||
if i > m then
|
||||
from
|
||||
h := j
|
||||
until
|
||||
h > r
|
||||
loop
|
||||
merged.force(ar.item(h),k+h-j)
|
||||
h := h+1
|
||||
end
|
||||
elseif j > m then
|
||||
from
|
||||
h := i
|
||||
until
|
||||
h > m
|
||||
loop
|
||||
merged.force(ar.item(h),k+h-i)
|
||||
h := h+1
|
||||
end
|
||||
end
|
||||
from
|
||||
h := l
|
||||
until
|
||||
h > r
|
||||
loop
|
||||
ar.item (h) := merged.item (h)
|
||||
h := h+1
|
||||
end
|
||||
ensure
|
||||
is_partially_sorted: is_sorted(ar, l,r)= TRUE
|
||||
end
|
||||
|
||||
is_sorted(ar: ARRAY[G];l, r: INTEGER): BOOLEAN
|
||||
--- feature is not required for mergesort but is used for contracts
|
||||
require
|
||||
ar_not_empty: ar.is_empty= FALSE
|
||||
l_in_range: l >= 1
|
||||
r_in_range: r <= ar.count
|
||||
local
|
||||
smaller : BOOLEAN
|
||||
i: INTEGER
|
||||
do
|
||||
smaller:= TRUE
|
||||
from
|
||||
i:= l
|
||||
until
|
||||
i=r
|
||||
loop
|
||||
if ar[i]> ar[i+1] then
|
||||
smaller:= FALSE
|
||||
end
|
||||
i:= i+1
|
||||
end
|
||||
if smaller = TRUE then
|
||||
RESULT := TRUE
|
||||
else
|
||||
RESULT:= FALSE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
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]
|
||||
end
|
||||
|
|
@ -2,9 +2,9 @@ import java.util.List;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class Merge {
|
||||
public static <E extends Comparable<? super E>> List<E> mergeSort(List<E> m) {
|
||||
if (m.size() <= 1) return m;
|
||||
public class Merge{
|
||||
public static <E extends Comparable<? super E>> List<E> mergeSort(List<E> m){
|
||||
if(m.size() <= 1) return m;
|
||||
|
||||
int middle = m.size() / 2;
|
||||
List<E> left = m.subList(0, middle);
|
||||
|
|
@ -17,33 +17,35 @@ public class Merge {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static <E extends Comparable<? super E>> List<E> merge(List<E> left, List<E> right) {
|
||||
public static <E extends Comparable<? super E>> List<E> merge(List<E> left, List<E> right){
|
||||
List<E> result = new ArrayList<E>();
|
||||
Iterator<E> it1 = left.iterator();
|
||||
Iterator<E> it2 = right.iterator();
|
||||
|
||||
E x = it1.next();
|
||||
E y = it2.next();
|
||||
while (true) {
|
||||
while (true){
|
||||
//change the direction of this comparison to change the direction of the sort
|
||||
if (x.compareTo(y) <= 0) {
|
||||
if(x.compareTo(y) <= 0){
|
||||
result.add(x);
|
||||
if (it1.hasNext())
|
||||
if(it1.hasNext()){
|
||||
x = it1.next();
|
||||
else {
|
||||
}else{
|
||||
result.add(y);
|
||||
while (it2.hasNext())
|
||||
while(it2.hasNext()){
|
||||
result.add(it2.next());
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}else{
|
||||
result.add(y);
|
||||
if (it2.hasNext())
|
||||
if(it2.hasNext()){
|
||||
y = it2.next();
|
||||
else {
|
||||
}else{
|
||||
result.add(x);
|
||||
while (it1.hasNext())
|
||||
while (it1.hasNext()){
|
||||
result.add(it1.next());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
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();
|
||||
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();
|
||||
}
|
||||
function mSort(arr,tmp,l){
|
||||
if(l==1)return;
|
||||
var m=Math.floor(l/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),l-m);
|
||||
merge(tmp_l,tmp_r,arr);
|
||||
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);
|
||||
}
|
||||
function merge_sort(arr){
|
||||
mSort(arr,arr.slice(),arr.length);
|
||||
function merge_sort(arr) {
|
||||
mSort(arr, arr.slice(), arr.length);
|
||||
}
|
||||
|
||||
var arr=[1,5,2,7,3,9,4,6,8];
|
||||
merge_sort(arr); // arr will now: 1,2,3,4,5,6,7,8,9
|
||||
var arr = [1, 5, 2, 7, 3, 9, 4, 6, 8];
|
||||
merge_sort(arr); // arr will now: 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
fn mergesort arr =
|
||||
(
|
||||
local left = #()
|
||||
local right = #()
|
||||
local result = #()
|
||||
if arr.count < 2 then return arr
|
||||
else
|
||||
(
|
||||
local mid = arr.count/2
|
||||
for i = 1 to mid do
|
||||
(
|
||||
append left arr[i]
|
||||
)
|
||||
for i = (mid+1) to arr.count do
|
||||
(
|
||||
append right arr[i]
|
||||
)
|
||||
left = mergesort left
|
||||
right = mergesort right
|
||||
if left[left.count] <= right[1] do
|
||||
(
|
||||
join left right
|
||||
return left
|
||||
)
|
||||
result = _merge left right
|
||||
return result
|
||||
)
|
||||
)
|
||||
|
||||
fn _merge a b =
|
||||
(
|
||||
local result = #()
|
||||
while a.count > 0 and b.count > 0 do
|
||||
(
|
||||
if a[1] <= b[1] then
|
||||
(
|
||||
append result a[1]
|
||||
a = for i in 2 to a.count collect a[i]
|
||||
)
|
||||
else
|
||||
(
|
||||
append result b[1]
|
||||
b = for i in 2 to b.count collect b[i]
|
||||
)
|
||||
)
|
||||
if a.count > 0 do
|
||||
(
|
||||
join result a
|
||||
)
|
||||
if b.count > 0 do
|
||||
(
|
||||
join result b
|
||||
)
|
||||
return result
|
||||
)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
a = for i in 1 to 15 collect random -5 20
|
||||
#(-3, 13, 2, -2, 13, 9, 17, 7, 16, 19, 0, 0, 20, 18, 1)
|
||||
mergeSort a
|
||||
#(-3, -2, 0, 0, 1, 2, 7, 9, 13, 13, 16, 17, 18, 19, 20)
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
{$IFDEF FPC}
|
||||
{$MODE DELPHI}
|
||||
{$OPTIMIZATION ON,Regvar,ASMCSE,CSE,PEEPHOLE}
|
||||
{$ELSE}
|
||||
{$APPTYPE CONSOLE}
|
||||
{$ENDIF}
|
||||
uses
|
||||
sysutils; //for timing
|
||||
type
|
||||
tDataElem = record
|
||||
myX,
|
||||
myY : double;
|
||||
myTag,
|
||||
myOrgIdx : LongInt;
|
||||
end;
|
||||
tpDataElem = ^tDataElem;
|
||||
tData = array of tDataElem;
|
||||
|
||||
tSortData = array of tpDataElem;
|
||||
tCompFunc = function(A,B:tpDataElem):integer;
|
||||
var
|
||||
Data : tData;
|
||||
Sortdata,
|
||||
tmpData : tSortData;
|
||||
|
||||
procedure InitData(var D:tData;cnt: LongWord);
|
||||
var
|
||||
i,k: LongInt;
|
||||
begin
|
||||
Setlength(D,cnt);
|
||||
Setlength(SortData,cnt);
|
||||
Setlength(tmpData,cnt shr 1 +1 );
|
||||
k := 10*cnt;
|
||||
For i := cnt-1 downto 0 do
|
||||
Begin
|
||||
Sortdata[i] := @D[i];
|
||||
with D[i] do
|
||||
Begin
|
||||
myX := Random*k;
|
||||
myY := Random*k;
|
||||
myTag := Random(k);
|
||||
myOrgIdx := i;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure FreeData(var D:tData);
|
||||
begin
|
||||
Setlength(tmpData,0);
|
||||
Setlength(SortData,0);
|
||||
Setlength(D,0);
|
||||
end;
|
||||
|
||||
function myCompX(A,B:tpDataElem):integer;
|
||||
//same as sign without jumps in assembler code
|
||||
Begin
|
||||
result := ORD(A^.myX > B^.myX)-ORD(A^.myX < B^.myX);
|
||||
end;
|
||||
|
||||
function myCompY(A,B:tpDataElem):integer;
|
||||
Begin
|
||||
result := ORD(A^.myY > B^.myY)-ORD(A^.myY < B^.myY);
|
||||
end;
|
||||
|
||||
function myCompTag(A,B:tpDataElem):integer;
|
||||
Begin
|
||||
result := ORD(A^.myTag > B^.myTag)-ORD(A^.myTag < B^.myTag);
|
||||
end;
|
||||
|
||||
procedure InsertionSort(left,right:integer;var a: tSortData;CompFunc: tCompFunc);
|
||||
var
|
||||
Pivot : tpDataElem;
|
||||
i,j : LongInt;
|
||||
begin
|
||||
for i:=left+1 to right do
|
||||
begin
|
||||
j :=i;
|
||||
Pivot := A[j];
|
||||
while (j>left) AND (CompFunc(A[j-1],Pivot)>0) do
|
||||
begin
|
||||
A[j] := A[j-1];
|
||||
dec(j);
|
||||
end;
|
||||
A[j] :=PiVot;// s.o.
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure mergesort(left,right:integer;var a: tSortData;CompFunc: tCompFunc);
|
||||
var
|
||||
i,j,k,mid :integer;
|
||||
begin
|
||||
{// without insertion sort
|
||||
If right>left then
|
||||
}
|
||||
//{ test insertion sort
|
||||
If right-left<=14 then
|
||||
InsertionSort(left,right,a,CompFunc)
|
||||
else
|
||||
//}
|
||||
begin
|
||||
//recursion
|
||||
mid := (right+left) div 2;
|
||||
mergesort(left, mid,a,CompFunc);
|
||||
mergesort(mid+1, right,a,CompFunc);
|
||||
//already sorted ?
|
||||
IF CompFunc(A[Mid],A[Mid+1])<0 then
|
||||
exit;
|
||||
|
||||
//########## Merge ##########
|
||||
//copy lower half to temporary array
|
||||
move(A[left],tmpData[0],(mid-left+1)*SizeOf(Pointer));
|
||||
i := 0;
|
||||
j := mid+1;
|
||||
k := left;
|
||||
// re-integrate
|
||||
while (k<j) AND (j<=right) do
|
||||
begin
|
||||
IF CompFunc(tmpData[i],A[j])<=0 then
|
||||
begin
|
||||
A[k] := tmpData[i];
|
||||
inc(i);
|
||||
end
|
||||
else
|
||||
begin
|
||||
A[k]:= A[j];
|
||||
inc(j);
|
||||
end;
|
||||
inc(k);
|
||||
end;
|
||||
//the rest of tmpdata a move should do too, in next life
|
||||
while (k<j) do
|
||||
begin
|
||||
A[k] := tmpData[i];
|
||||
inc(i);
|
||||
inc(k);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
T1,T0: TDateTime;
|
||||
i : integer;
|
||||
Begin
|
||||
randomize;
|
||||
InitData(Data,1*1000*1000);
|
||||
|
||||
T0 := Time;
|
||||
mergesort(Low(SortData),High(SortData),SortData,@myCompX);
|
||||
T1 := Time;
|
||||
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
|
||||
Write(i:8);
|
||||
|
||||
T0 := Time;
|
||||
mergesort(Low(SortData),High(SortData),SortData,@myCompY);
|
||||
T1 := Time;
|
||||
Writeln('myY ',FormatDateTime('NN:SS.ZZZ',T1-T0));
|
||||
|
||||
T0 := Time;
|
||||
mergesort(Low(SortData),High(SortData),SortData,@myCompTag);
|
||||
T1 := Time;
|
||||
Writeln('myTag ',FormatDateTime('NN:SS.ZZZ',T1-T0));
|
||||
|
||||
FreeData (Data);
|
||||
end.
|
||||
|
|
@ -4,7 +4,7 @@ def merge_sort(m):
|
|||
if len(m) <= 1:
|
||||
return m
|
||||
|
||||
middle = len(m) / 2
|
||||
middle = len(m) // 2
|
||||
left = m[:middle]
|
||||
right = m[middle:]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,63 +1,57 @@
|
|||
/*REXX program sorts a (stemmed) array using the merge-sort method. */
|
||||
call gen@ /*generate the array elements. */
|
||||
call show@ 'before sort' /*show the before array elements.*/
|
||||
call mergeSort highItem /*invoke the merge sort for array*/
|
||||
call show@ ' after sort' /*show the after array elements.*/
|
||||
/*REXX program sorts a (stemmed) array using the merge─sort algorithm.*/
|
||||
call gen@; w=length(#) /*generate an array (@.) of items*/
|
||||
call show@ 'before sort' /*show the before array elements.*/
|
||||
call mergeSort # /*invoke the merge sort for array*/
|
||||
call show@ ' after sort' /*show the after array elements.*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────GEN@ subroutine─────────────────────*/
|
||||
gen@: @.= /*assign default value for @ stem*/
|
||||
@.1='---The seven deadly sins---' /*everybody: pick your favorite.*/
|
||||
@.2='==========================='
|
||||
@.3='pride'
|
||||
@.4='avarice'
|
||||
@.5='wrath'
|
||||
@.6='envy'
|
||||
@.7='gluttony'
|
||||
@.8='sloth'
|
||||
@.9='lust'
|
||||
do highItem=1 while @.highItem\=='' /*find number of entries*/
|
||||
end
|
||||
highItem=highItem-1 /*adjust highItem by -1.*/
|
||||
return
|
||||
/*──────────────────────────────────MERGETO@ subroutine─────────────────*/
|
||||
mergeTo@: procedure expose @. !.; parse arg L,n; if n==1 then return
|
||||
if n==2 then do; h=L+1
|
||||
if @.L>@.h then do; _=@.h; @.h=@.L; @.L=_; end
|
||||
return
|
||||
end
|
||||
m=n%2
|
||||
call mergeTo@ L+m,n-m
|
||||
call mergeTo! L,m,1
|
||||
i=1; j=L+m; do k=L while k<j
|
||||
if j==L+n | !.i<=@.j then do; @.k=!.i; i=i+1; end
|
||||
else do; @.k=@.j; j=j+1; end
|
||||
end /*k*/
|
||||
gen@: @. = /*assign default value for @ stem*/
|
||||
@.1 = '---The seven deadly sins---' /*pick a favorite.*/
|
||||
@.2 = '==========================='
|
||||
@.3 = 'pride'
|
||||
@.4 = 'avarice'
|
||||
@.5 = 'wrath'
|
||||
@.6 = 'envy'
|
||||
@.7 = 'gluttony'
|
||||
@.8 = 'sloth'
|
||||
@.9 = 'lust'
|
||||
do #=1 while @.#\==''; end; #=#-1 /*find the number of entries in @*/
|
||||
return
|
||||
/*──────────────────────────────────MERGESORT subroutine────────────────*/
|
||||
mergeSort: procedure expose @.; call mergeTo@ 1,arg(1)
|
||||
mergeSort: procedure expose @.; call mergeTo@ 1,arg(1); return
|
||||
/*──────────────────────────────────MERGETO@ subroutine─────────────────*/
|
||||
mergeTo@: procedure expose @. !.; parse arg L,n ; if n==1 then return
|
||||
if n==2 then do; h=L+1 /*handle special case of 2 items.*/
|
||||
if @.L>@.h then do; _=@.h; @.h=@.L; @.L=_; end
|
||||
return
|
||||
end
|
||||
m=n%2 /*cut N in half (integer div.)*/
|
||||
call mergeTo@ L+m,n-m /*divide items to the left ···*/
|
||||
call mergeTo! L,m,1 /* " " " " right ···*/
|
||||
i=1; j=L+m; do k=L while k<j /*whilst items on right···*/
|
||||
if j==L+n | !.i<=@.j then do; @.k=!.i; i=i+1; end
|
||||
else do; @.k=@.j; j=j+1; end
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────MERGETO! subroutine─────────────────*/
|
||||
mergeTo!: procedure expose @. !.; parse arg L,n,_
|
||||
if n==1 then do; !._=@.L; return; end
|
||||
if n==2 then do
|
||||
h=L+1; q=1+_
|
||||
if @.L>@.h then do; q=_; _=q+1; end
|
||||
!._=@.L; !.q=@.h
|
||||
return
|
||||
end
|
||||
m=n%2
|
||||
call mergeTo@ L,m
|
||||
call mergeTo! L+m,n-m,m+_
|
||||
i=L; j=m+_
|
||||
do k=_ while k<j
|
||||
if j==n+_ | @.i<=!.j then do; !.k=@.i; i=i+1; end
|
||||
else do; !.k=!.j; j=j+1; end
|
||||
end /*k*/
|
||||
mergeTo!: procedure expose @. !.; parse arg L,n,_
|
||||
if n==1 then do; !._=@.L; return; end /*handle special case of 1 item. */
|
||||
if n==2 then do /* " " " " 2 items.*/
|
||||
h=L+1; q=1+_
|
||||
if @.L>@.h then do; q=_; _=q+1; end
|
||||
!._=@.L; !.q=@.h
|
||||
return /*done with special case of N=2.*/
|
||||
end
|
||||
m=n%2 /*cut N in half (integer div).*/
|
||||
call mergeTo@ L,m /*divide items to the left ···*/
|
||||
call mergeTo! L+m,n-m,m+_ /* " " " " right ···*/
|
||||
i=L; j=m+_; do k=_ while k<j /*whilst items on left ···*/
|
||||
if j==_+n | @.i<=!.j then do; !.k=@.i; i=i+1; end
|
||||
else do; !.k=!.j; j=j+1; end
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────SHOW@ subroutine────────────────────*/
|
||||
show@: widthH=length(highItem) /*maximum the width of any line. */
|
||||
do j=1 for highItem
|
||||
say 'element' right(j,widthH) arg(1)':' @.j
|
||||
end /*j*/
|
||||
say copies('─',60) /*show a seperator line (fence). */
|
||||
show@: say copies('▒',70); do j=1 for #; pad=left('',10) /*indent.*/
|
||||
say pad 'element' right(j,w) arg(1)':' @.j
|
||||
end /*j*/
|
||||
return
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ def merge_sort(m)
|
|||
return m if m.length <= 1
|
||||
|
||||
middle = m.length / 2
|
||||
left = m[0,middle]
|
||||
left = m[0..middle - 1]
|
||||
right = m[middle..-1]
|
||||
|
||||
left = merge_sort(left)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ class Array
|
|||
return self if length <= 1
|
||||
comparitor ||= lambda {|a, b| a <=> b}
|
||||
middle = length / 2
|
||||
left = self[0, middle].mergesort(&comparitor)
|
||||
left = self[0..middle - 1].mergesort(&comparitor)
|
||||
right = self[middle..-1].mergesort(&comparitor)
|
||||
merge(left, right, comparitor)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
(append) list1 list2
|
||||
comment:
|
||||
#true
|
||||
(003) "append" list1 list2
|
||||
|
||||
(car) pair
|
||||
comment:
|
||||
#true
|
||||
(002) "car" pair
|
||||
|
||||
(cdr) pair
|
||||
comment:
|
||||
#true
|
||||
(002) "cdr" pair
|
||||
|
||||
(cons) one two
|
||||
comment:
|
||||
#true
|
||||
(003) "cons" one two
|
||||
|
||||
(map) function list
|
||||
comment:
|
||||
#true
|
||||
(003) "map" function list
|
||||
|
||||
(merge) comparator list1 list2
|
||||
comment:
|
||||
#true
|
||||
(merge1) comparator list1 list2 nil
|
||||
|
||||
(merge1) comparator list1 list2 collect
|
||||
comment:
|
||||
(null?) list2
|
||||
(append) (reverse) collect list1
|
||||
|
||||
(merge1) comparator list1 list2 collect
|
||||
comment:
|
||||
(null?) list1
|
||||
(append) (reverse) collect list2
|
||||
|
||||
(merge1) comparator list1 list2 collect
|
||||
comment:
|
||||
(003) comparator (car) list2 (car) list1
|
||||
(merge1) comparator list1 (cdr) list2 (cons) (car) list2 collect
|
||||
|
||||
(merge1) comparator list1 list2 collect
|
||||
comment:
|
||||
#true
|
||||
(merge1) comparator (cdr) list1 list2 (cons) (car) list1 collect
|
||||
|
||||
(null?) value
|
||||
comment:
|
||||
#true
|
||||
(002) "null?" value
|
||||
|
||||
(reverse) list
|
||||
comment:
|
||||
#true
|
||||
(002) "reverse" list
|
||||
|
||||
(sort) comparator jumble
|
||||
comment:
|
||||
#true
|
||||
(car) (sort11) comparator (sort1) jumble
|
||||
|
||||
(sort1) jumble
|
||||
comment:
|
||||
#true
|
||||
(map) "list" jumble
|
||||
|
||||
(sort11) comparator jumble
|
||||
comment:
|
||||
(null?) jumble
|
||||
nil
|
||||
|
||||
(sort11) comparator jumble
|
||||
comment:
|
||||
(null?) (cdr) jumble
|
||||
jumble
|
||||
|
||||
(sort11) comparator jumble
|
||||
comment:
|
||||
#true
|
||||
(sort11) comparator
|
||||
(cons) (merge) comparator (car) jumble (002) "cadr" jumble
|
||||
(sort11) comparator (002) "cddr" jumble
|
||||
Loading…
Add table
Add a link
Reference in a new issue