使用QuickSort快速排序算法,排序一个链表。
下面是quickSort,因为quickSort算法的最坏情况是O(n*n), 所以如果做LeetCode上的Sort List这道题目,会遇上最坏情况超时的,不过这是个很好的算法,故此贴出来。
参考网站:
http://www.geeksforgeeks.org/quicksort-on-singly-linked-list/
也看了有些博客或什么网站也写有quickSort排序链表的文章,注意看清楚了,很多并不是真正的链表排序,而是排序了链表的值,那样并不是链表操作,不能算链表的quicksort。
有几个地方需要注意的:
1 分成两个链表的时候,注意把结尾=NULL,重新合并中间的pivot不要忘了,不然会断链的。
2 指针传递要注意:指针值传递和指针地址传递
class Solution2QuickSort {
public:
ListNode *sortList(ListNode *head)
{
return quickSort(head, getTail(head));
}
ListNode *getTail(ListNode *h)
{
while (h && h->next) h = h->next;
return h;
}
ListNode *partition(ListNode *h, ListNode *t, ListNode **nh, ListNode **nt)
{
ListNode *pivot = t;
ListNode *pre = NULL, *cur = h, *tail = t;
while (cur != pivot)
{
if (cur->val < pivot->val)
{
if (!(*nh)) (*nh) = cur; //注意:不能是nh=&cur
pre = cur;
cur = cur->next;
}
else
{
if (pre) pre->next = cur->next;
ListNode *tmp = cur->next;
cur->next = pivot->next;
pivot->next = cur;
cur = tmp;
if (tail == t) tail = tail->next;
}
}
if (!(*nh)) (*nh) = pivot;
(*nt) = tail;
return pivot;
}
ListNode *quickSort(ListNode *h, ListNode *t)
{
if (!h || h == t) return h;
ListNode *nh = nullptr, *nt = nullptr;
ListNode *pivot = partition(h,t,&nh,&nt);
if (nh != pivot)
{
ListNode *tmp = nh;
while (tmp->next != pivot) tmp = tmp->next;
tmp->next = nullptr;
nh = quickSort(nh, tmp);
tmp = getTail(nh);
tmp->next = pivot;
}
pivot->next = quickSort(pivot->next, nt);
return nh;
}
};