看了《啊哈!算法》之后,发现自己对于快速排序已经有了理解了。而且那张可爱小人的图也记在心里了。
但是看到LeetCode单链表排序的时候,还是有点不知道能不能用上。第一次查的时候很多答案都说是归并排序,但是这块内容还没有学过,所以就想先放一放。
单链表想如同数组一样实现快排最大的问题在于没有尾指针向前。因此,我第一时间可以判断如果是双向链表结构,应该是可以照搬实现的。
博客http://blog.csdn.net/otuhacker/article/details/10366563完整给出了单链表快速排序内容,但是快速排序本质上是实现分组排序,啊哈磊把算法如何进行说的很清楚,但是事实上现在想想那个已经算是在数组中实现快排做了优化的了。比如他说要尾端的j先--,达到相应位置之后i++去找。
看了博客内容之后,我就发现有一个快排思想我一直都忽略掉了:就是不断把要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小。这就叫快排了。所以,单链表的快排相当于不好优化的初级版快速排序呗。选取待排序的子序列第一个作为基准元素,就两个指针从前向后找,一个找比基准大的,一个找比基准小的,然后交换。当子序列遍历过了,将此时最后一个找到的大的和基准元素的交换,一次排序结束。接下来就是递归操作了,这点和普通的快速排序差不多。
最后给出我自己在LeetCode上的实现代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *fast_sort(ListNode *head,ListNode *end)
{
ListNode *p=head;
int num=head->val,temp;
ListNode *q=p->next;
if((head==end)||(head->next==end))
return head;
while(q!=end)
{
if(q->val<num)
{
p=p->next;
temp=p->val;
p->val=q->val;
q->val=temp;
}
q=q->next;
}
temp=p->val;
p->val=head->val;
head->val=temp;
fast_sort(head,p);
fast_sort(p->next,end);
return head;
}
ListNode *sortList(ListNode *head) {
if((head==NULL)||(head->next==NULL))
return head;
fast_sort(head,NULL);
return head;
}
};
但是有个我不太明白的地方,我第一次把(head->next==NULL)写成了head->next=NULL,结果提示我算例未通过,说给出算例为{1,2},我的输出是{2}。
但是这个算例送进来,if条件不为真啊,怎么会影响输出呢?