mirror of https://github.com/inolen/redream.git
removed list_sort
This commit is contained in:
parent
7b0b47a641
commit
b7d48e68f7
|
@ -50,83 +50,3 @@ void list_remove(struct list *list, struct list_node *n) {
|
|||
void list_clear(struct list *list) {
|
||||
list->head = list->tail = NULL;
|
||||
}
|
||||
|
||||
/* implements the mergesort for linked lists as described at
|
||||
http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html */
|
||||
void list_sort(struct list *list, list_node_cmp cmp) {
|
||||
struct list_node *head = list->head;
|
||||
struct list_node *tail = NULL;
|
||||
int k = 1;
|
||||
|
||||
while (1) {
|
||||
int merges = 0;
|
||||
struct list_node *p = head;
|
||||
|
||||
head = NULL;
|
||||
tail = NULL;
|
||||
|
||||
while (p) {
|
||||
/* track the number of lists merged this pass */
|
||||
merges++;
|
||||
|
||||
/* step q forward k places, tracking the size of p */
|
||||
int psize = 0;
|
||||
int qsize = k;
|
||||
struct list_node *q = p;
|
||||
while (psize < k && q) {
|
||||
psize++;
|
||||
q = q->next;
|
||||
}
|
||||
|
||||
/* merge the list starting at p of length psize with the list starting
|
||||
at q of at most, length qsize */
|
||||
while (psize || (qsize && q)) {
|
||||
struct list_node *next;
|
||||
|
||||
if (!psize) {
|
||||
next = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
} else if (!qsize || !q) {
|
||||
next = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
} else if (cmp(q, p) < 0) {
|
||||
next = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
} else {
|
||||
next = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
}
|
||||
|
||||
/* move merged node to tail */
|
||||
if (!tail) {
|
||||
head = next;
|
||||
} else {
|
||||
tail->next = next;
|
||||
}
|
||||
next->prev = tail;
|
||||
tail = next;
|
||||
}
|
||||
|
||||
p = q;
|
||||
}
|
||||
|
||||
if (tail) {
|
||||
tail->next = NULL;
|
||||
}
|
||||
|
||||
/* if only 1 pair of lists was merged, this is the end */
|
||||
if (merges <= 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
k *= 2;
|
||||
}
|
||||
|
||||
/* update internal head and tail with sorted head and tail */
|
||||
list->head = head;
|
||||
list->tail = tail;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ void list_add_after(struct list *list, struct list_node *after,
|
|||
struct list_node *n);
|
||||
void list_remove(struct list *list, struct list_node *n);
|
||||
void list_clear(struct list *list);
|
||||
void list_sort(struct list *list, list_node_cmp cmp);
|
||||
|
||||
#define list_for_each(list, it) \
|
||||
for (struct list_node *it = (list)->head, *it##_next = it ? it->next : NULL; \
|
||||
|
|
|
@ -114,31 +114,3 @@ TEST(intrusive_list_remove_clear) {
|
|||
|
||||
CHECK(list_empty(&people));
|
||||
}
|
||||
|
||||
/* sort tests */
|
||||
int person_sort(const struct list_node *list_lhs,
|
||||
const struct list_node *list_rhs) {
|
||||
const struct person *lhs = list_entry(list_lhs, const struct person, it);
|
||||
const struct person *rhs = list_entry(list_rhs, const struct person, it);
|
||||
/* sort in descending order */
|
||||
return strcmp(rhs->name, lhs->name);
|
||||
}
|
||||
|
||||
TEST(intrusive_list_empty_sort) {
|
||||
struct list people = {0};
|
||||
|
||||
list_sort(&people, &person_sort);
|
||||
|
||||
CHECK(list_empty(&people));
|
||||
}
|
||||
|
||||
TEST(intrusive_list_sort) {
|
||||
struct list people = {0};
|
||||
init_people(&people);
|
||||
|
||||
list_sort(&people, &person_sort);
|
||||
|
||||
struct person *expected[] = {&ccc, &bbb, &aaa};
|
||||
int num_expected = array_size(expected);
|
||||
validate_people(&people, expected, num_expected);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue