diff options
author | 2021-02-21 13:16:54 +0200 | |
---|---|---|
committer | 2021-02-21 13:19:06 +0200 | |
commit | 29712a5098842ea3930ec00ddd1c0b9d264ba9b5 (patch) | |
tree | 3744b445acb971342be18fa6d2c9c4c20a470e1d /src/mergesort.c | |
parent | 26ab990a747ab675bcff32a40734dcb61468f652 (diff) | |
download | algos-ld1-29712a5098842ea3930ec00ddd1c0b9d264ba9b5.tar.gz algos-ld1-29712a5098842ea3930ec00ddd1c0b9d264ba9b5.tar.bz2 algos-ld1-29712a5098842ea3930ec00ddd1c0b9d264ba9b5.zip |
in-memory array sorting: GET!
lists need a bit more work and after that, in-file should shortly
follow.
Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
Diffstat (limited to 'src/mergesort.c')
-rw-r--r-- | src/mergesort.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/mergesort.c b/src/mergesort.c index c431b31..7391544 100644 --- a/src/mergesort.c +++ b/src/mergesort.c @@ -5,42 +5,49 @@ #include <errno.h> #include <stdlib.h> #include "defs.h" -#include "io.h" +#include "stream.h" #include "mergesort.h" +static int merge(struct stream * const dest, struct stream * const A, struct stream * const B); + /* bottom-up variantas */ int merge_sort(struct stream * const src, struct stream * const dest) { int ret = 0; - struct stream tmp[4]; /* I can't into stream reuse, hence four. A yeet, followed by a dab. */ + struct stream tmp[4] = {0}; /* I can't into stream reuse, hence four. A yeet, followed by a dab. */ size_t i; try(!src || !dest, err, EINVAL, "cannot sort what's not there"); - if (src->n > 1) { /* stream of size one is inherently sorted */ + try_s((ret = stream_shallow_copy(src, dest)), err); + + if (src->n > 1) { src->split(src, tmp, tmp + 2); /* split stream in half */ - merge_sort(tmp + 1, tmp); /* recurse-sort first half */ - merge_sort(tmp + 3, tmp + 2); /* recurse-sort second half */ - merge(dest, tmp, tmp + 2); /* merge the two halves back */ - } + merge_sort(tmp, tmp + 1); /* recurse-sort first half */ + merge_sort(tmp + 2, tmp + 3); /* recurse-sort second half */ + merge(dest, tmp + 1, tmp + 3); /* merge the two halves back */ + dest->rewind(dest); - for (i = 0; i < (sizeof(tmp) / sizeof(*tmp)); ++i) { - stream_close(tmp + i); + for (i = 0; i < (sizeof(tmp) / sizeof(*tmp)); ++i) { + stream_close(tmp + i); + } + } else { /* stream of size one is inherently sorted, simply src with dest */ + *tmp = *dest; + *dest = *src; + *src = *tmp; } err: return ret; } -int merge(struct stream * const dest, struct stream * const A, struct stream * const B) +static int merge(struct stream * const dest, struct stream * const A, struct stream * const B) { int ret = 0; struct entry_l *a; struct entry_l *b; - try(A->parentid != B->parentid, err, EINVAL, "cannot merge blocks: uncommon parent!"); - a = get(A); b = get(B); @@ -54,7 +61,6 @@ int merge(struct stream * const dest, struct stream * const A, struct stream * c } } -err: return ret; } |