之前有一篇文章介绍了glib库中单双向链表的排序采用了归并排序,并且不需要额外的空间,这篇文章将介绍c-algorithms库中单双向链表的快速排序过程:
通常快速排序算法都是施行于数组,但它也可以作用于单链表(这里以单向链表为例)。
原理跟数组快速排序是一样的,先partition,然后再递归的解决子单链表的快速排序。
以下是从c-algorithms代码中摘下来的代码段:
static SListEntry *slist_sort_internal(SListEntry **list,
SListCompareFunc compare_func)
{
SListEntry *pivot;
SListEntry *rover;
SListEntry *less_list, *more_list;
SListEntry *less_list_end, *more_list_end;
/* If there are less than two entries in this list, it is
* already sorted */
if (*list == NULL || (*list)->next == NULL) {
return *list;
}
/* The first entry is the pivot */
pivot = *list;
/* Iterate over the list, starting from the second entry. Sort
* all entries into the less and more lists based on comparisons
* with the pivot */
less_list = NULL;
more_list = NULL;
rover = (*list)->next;
while (rover != NULL) {
SListEntry *next = rover->next;
if (compare_func(rover->data, pivot->data) < 0) {
/* Place this in the less list */
rover->next = less_list;
less_list = rover;
} else {
/* Place this in the more list */
rover->next = more_list;
more_list = rover;
}
rover = next;
}
/* Sort the sublists recursively */
less_list_end = slist_sort_internal(&less_list, compare_func);
more_list_end = slist_sort_internal(&more_list, compare_func);
/* Create the new list starting from the less list */
*list = less_list;
/* Append the pivot to the end of the less list. If the less list
* was empty, start from the pivot */
if (less_list == NULL) {
*list = pivot;
} else {
less_list_end->next = pivot;
}
/* Append the more list after the pivot */
pivot->next = more_list;
/* Work out what the last entry in the list is. If the more list was
* empty, the pivot was the last entry. Otherwise, the end of the
* more list is the end of the total list. */
if (more_list == NULL) {
return pivot;
} else {
return more_list_end;
}
}
void slist_sort(SListEntry **list, SListCompareFunc compare_func)
{
slist_sort_internal(list, compare_func);
}