September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue