Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -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.

View file

@ -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;
}

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -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;
}
}

View file

@ -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

View file

@ -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
)

View file

@ -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)

View file

@ -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.

View file

@ -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:]

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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