libcdsb/src/list/sort.c
2022-06-05 18:35:14 +03:00

65 lines
1.4 KiB
C

/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
/*#####################################################################################################################*/
static inline void lnode_swap(lnode_t* s0, lnode_t* s1) {
vnode_t v = s0->node;
vtype t = s0->type;
s0->node = s1->node;
s0->type = s1->type;
s1->node = v;
s1->type = t;
}
static inline lnode_t* pivot(lnode_t *l, lnode_t *r) {
lnode_t *c = l->prev;
for (lnode_t* i = l; i != r; i = i->next) {
if (lnode_compare(i, r) < 0) {
c = (is_null(c)) ? l : c->next;
lnode_swap(c, i);
}
}
c = (is_null(c)) ? l : c->next;
lnode_swap(c, r);
return c;
}
static void quick_sort(lnode_t* l, lnode_t* r) {
lnode_t* p;
if (!is_null(r) && l != r && l != r->next) {
p = pivot(l, r);
quick_sort(l, p->prev);
quick_sort(p->next, r);
}
}
/*#####################################################################################################################*/
void list_sort(list_t* x) {
return quick_sort(x->first, x->last);
}
void list_reverse(list_t* x) {
lnode_t *l = x->first;
lnode_t *r = x->last;
while (l != r) {
lnode_swap(l, r);
if ((r = r->prev) == l)
break;
l = l->next;
}
}