September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -0,0 +1,15 @@
|
|||
fun mergeSort(m):
|
||||
return m if m.size <= 1
|
||||
let middle = m.size / 2
|
||||
let left = merge(m[:middle])
|
||||
let right = merge(m[middle:]);
|
||||
|
||||
fun merge(left, right):
|
||||
let result = []
|
||||
while |left or right|.!empty:
|
||||
result ++ (left.shift() if |left <= right|.first ...
|
||||
else right.shift())
|
||||
result ++ left ++ right
|
||||
|
||||
let arr = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
|
||||
print mergeSort arr
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
inline
|
||||
void merge(int *left, int l_len, int *right, int r_len, int *out)
|
||||
{
|
||||
int i, j, k;
|
||||
for (i = j = k = 0; i < l_len && j < r_len; )
|
||||
out[k++] = left[i] < right[j] ? left[i++] : right[j++];
|
||||
|
||||
while (i < l_len) out[k++] = left[i++];
|
||||
while (j < r_len) out[k++] = right[j++];
|
||||
}
|
||||
|
||||
/* inner recursion of merge sort */
|
||||
void recur(int *buf, int *tmp, int len)
|
||||
{
|
||||
int l = len / 2;
|
||||
if (len <= 1) return;
|
||||
|
||||
/* note that buf and tmp are swapped */
|
||||
recur(tmp, buf, l);
|
||||
recur(tmp + l, buf + l, len - l);
|
||||
|
||||
merge(tmp, l, tmp + l, len - l, buf);
|
||||
}
|
||||
|
||||
/* preparation work before recursion */
|
||||
void merge_sort(int *buf, int len)
|
||||
{
|
||||
/* call alloc, copy and free only once */
|
||||
int *tmp = malloc(sizeof(int) * len);
|
||||
memcpy(tmp, buf, sizeof(int) * len);
|
||||
|
||||
recur(buf, tmp, len);
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
# define LEN 20
|
||||
int i, x[LEN];
|
||||
|
||||
for (i = 0; i < LEN; i++)
|
||||
x[i] = rand() % LEN;
|
||||
|
||||
puts("before sort:");
|
||||
for (i = 0; i < LEN; i++) printf("%d ", x[i]);
|
||||
putchar('\n');
|
||||
|
||||
merge_sort(x, LEN);
|
||||
|
||||
puts("after sort:");
|
||||
for (i = 0; i < LEN; i++) printf("%d ", x[i]);
|
||||
putchar('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct link_s *link, link_t;
|
||||
struct link_s { double v; link next; };
|
||||
|
||||
const link_t fnil = { 0./0., &fnil }; // sentinel
|
||||
const link const nil = &fnil;
|
||||
|
||||
link list_from_array(double *a, int len)
|
||||
{
|
||||
link p = nil;
|
||||
while (len--) {
|
||||
link pp = malloc(sizeof(*pp));
|
||||
pp->v = a[len];
|
||||
pp->next = p;
|
||||
p = pp;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void show_list(link a)
|
||||
{
|
||||
for (; a != nil; a = a->next)
|
||||
printf("%g ", a->v);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
link merge(link a, link b)
|
||||
{
|
||||
link head = &(link_t){0, nil}, tail = head;
|
||||
while (a != nil && b != nil) {
|
||||
link *p = a->v <= b->v ? &a : &b;
|
||||
tail->next = *p;
|
||||
*p = (*p)->next;
|
||||
tail = tail->next;
|
||||
}
|
||||
tail->next = a != nil ? a : b;
|
||||
return head->next;
|
||||
}
|
||||
|
||||
link merge_sort(link p)
|
||||
{
|
||||
if (p->next == nil) return p;
|
||||
|
||||
link tail = p, mid = p;
|
||||
// Seek to the middle of the list. This is O(n) for list
|
||||
// length, so O(n log n) complexity to overall merge sort
|
||||
// that an array wouldn't have to deal with.
|
||||
while (1) {
|
||||
tail = tail->next->next;
|
||||
if (tail == nil) break;
|
||||
mid = mid->next;
|
||||
}
|
||||
|
||||
tail = mid->next;
|
||||
mid->next = nil;
|
||||
|
||||
return merge(merge_sort(p), merge_sort(tail));
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
double x[] = {5,3,6,1,2,6,2,0,3,5,7,8,2,4,9};
|
||||
link p = list_from_array(x, sizeof(x)/sizeof(x[0]));
|
||||
|
||||
puts("list: "); show_list(p);
|
||||
puts("sort: "); show_list(merge_sort(p));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
' FB 1.05.0 Win64
|
||||
|
||||
Sub copyArray(a() As Integer, iBegin As Integer, iEnd As Integer, b() As Integer)
|
||||
Redim b(iBegin To iEnd - 1) As Integer
|
||||
For k As Integer = iBegin To iEnd - 1
|
||||
b(k) = a(k)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
' Left source half is a(iBegin To iMiddle-1).
|
||||
' Right source half is a(iMiddle To iEnd-1).
|
||||
' Result is b(iBegin To iEnd-1).
|
||||
Sub topDownMerge(a() As Integer, iBegin As Integer, iMiddle As Integer, iEnd As Integer, b() As Integer)
|
||||
Dim i As Integer = iBegin
|
||||
Dim j As Integer = iMiddle
|
||||
|
||||
' While there are elements in the left or right runs...
|
||||
For k As Integer = iBegin To iEnd - 1
|
||||
' If left run head exists and is <= existing right run head.
|
||||
If i < iMiddle AndAlso (j >= iEnd OrElse a(i) <= a(j)) Then
|
||||
b(k) = a(i)
|
||||
i += 1
|
||||
Else
|
||||
b(k) = a(j)
|
||||
j += 1
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
' Sort the given run of array a() using array b() as a source.
|
||||
' iBegin is inclusive; iEnd is exclusive (a(iEnd) is not in the set).
|
||||
Sub topDownSplitMerge(b() As Integer, iBegin As Integer, iEnd As Integer, a() As Integer)
|
||||
If (iEnd - iBegin) < 2 Then Return '' If run size = 1, consider it sorted
|
||||
' split the run longer than 1 item into halves
|
||||
Dim iMiddle As Integer = (iEnd + iBegin) \ 2 '' iMiddle = mid point
|
||||
' recursively sort both runs from array a() into b()
|
||||
topDownSplitMerge(a(), iBegin, iMiddle, b()) '' sort the left run
|
||||
topDownSplitMerge(a(), iMiddle, iEnd, b()) '' sort the right run
|
||||
' merge the resulting runs from array b() into a()
|
||||
topDownMerge(b(), iBegin, iMiddle, iEnd, a())
|
||||
End Sub
|
||||
|
||||
' Array a() has the items to sort; array b() is a work array (empty initially).
|
||||
Sub topDownMergeSort(a() As Integer, b() As Integer, n As Integer)
|
||||
copyArray(a(), 0, n, b()) '' duplicate array a() into b()
|
||||
topDownSplitMerge(b(), 0, n, a()) '' sort data from b() into a()
|
||||
End Sub
|
||||
|
||||
Sub printArray(a() As Integer)
|
||||
For i As Integer = LBound(a) To UBound(a)
|
||||
Print Using "####"; a(i);
|
||||
Next
|
||||
Print
|
||||
End Sub
|
||||
|
||||
Dim a(0 To 9) As Integer = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1}
|
||||
|
||||
Dim b() As Integer
|
||||
Print "Unsorted : ";
|
||||
printArray(a())
|
||||
topDownMergeSort a(), b(), 10
|
||||
Print "Sorted : ";
|
||||
printArray(a())
|
||||
Print
|
||||
Dim a2(0 To 8) As Integer = {7, 5, 2, 6, 1, 4, 2, 6, 3}
|
||||
Erase b
|
||||
Print "Unsorted : ";
|
||||
printArray(a2())
|
||||
topDownMergeSort a2(), b(), 9
|
||||
Print "Sorted : ";
|
||||
printArray(a2())
|
||||
Print
|
||||
Print "Press any key to quit"
|
||||
Sleep
|
||||
|
|
@ -1,29 +1,27 @@
|
|||
func merge(left, right) {
|
||||
var result = [];
|
||||
while (!left.is_empty && !right.is_empty) {
|
||||
result.append([right,left][left.first <= right.first].shift);
|
||||
};
|
||||
result + left + right;
|
||||
var result = []
|
||||
while (left && right) {
|
||||
result << [right,left].min_by{.first}.shift
|
||||
}
|
||||
result + left + right
|
||||
}
|
||||
|
||||
func mergesort(array) {
|
||||
var len = array.len;
|
||||
len < 2 && return array;
|
||||
var len = array.len
|
||||
len < 2 && return array
|
||||
|
||||
var mid = (len/2 -> int);
|
||||
var left = array.ft(0, mid-1);
|
||||
var right = array.ft(mid);
|
||||
var (left, right) = array.part(len//2)
|
||||
|
||||
left = __FUNC__(left);
|
||||
right = __FUNC__(right);
|
||||
left = __FUNC__(left)
|
||||
right = __FUNC__(right)
|
||||
|
||||
merge(left, right);
|
||||
merge(left, right)
|
||||
}
|
||||
|
||||
# Numeric sort
|
||||
var nums = (0..7 -> shuffle);
|
||||
say mergesort(nums);
|
||||
var nums = rand(1..100, 10)
|
||||
say mergesort(nums)
|
||||
|
||||
# String sort
|
||||
var strings = ('a'..'e' -> shuffle);
|
||||
say mergesort(strings);
|
||||
var strings = rand('a'..'z', 10)
|
||||
say mergesort(strings)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
fcn _merge(left,right){
|
||||
if (not left) return(right);
|
||||
if (not right) return(left);
|
||||
l:=left[0]; r:=right[0];
|
||||
if (l<=r) return(L(l).extend(self.fcn(left[1,*],right)));
|
||||
else return(L(r).extend(self.fcn(left,right[1,*])));
|
||||
}
|
||||
|
||||
fcn merge_sort(L){
|
||||
if (L.len()<2) return(L);
|
||||
n:=L.len()/2;
|
||||
return(_merge(self.fcn(L[0,n]), self.fcn(L[n,*])));
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
merge_sort(T(1,3,5,7,9,8,6,4,2)).println();
|
||||
merge_sort("big fjords vex quick waltz nymph").concat().println();
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
fcn mergeSort(L){
|
||||
if (L.len()<2) return(L.copy());
|
||||
n:=L.len()/2;
|
||||
self.fcn(L[0,n]).merge(self.fcn(L[n,*]));
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mergeSort(T(1,3,5,7,9,8,6,4,2)).println();
|
||||
mergeSort("big fjords vex quick waltz nymph".split("")).concat().println();
|
||||
Loading…
Add table
Add a link
Reference in a new issue