1.快速排序
首先:对于数组的快速排序思想是先找到一个left和一个right和一个基数,然后按照两个指针的相向运动并按照一定的规律交换值,最后找到一个支点,使得支点左边的值都小于支点,支点右边的值都大于支点。
但是单链表没有pre指针,如何找到这个支点呢?
我们只需要两个指针p和q,两个指针都往next的方向移动,移动的过程中始终保持p之前的key都小于选定的key,p和q之间的key都大于key,当q走到末尾的时候,就完成了支点的寻找。
代码如下:
struct node
{
int key;
node *next;
node(int nkey,node *pnext):key(nkey),next(pnext){}
};
node *getpartition(node *pbegin,node *pend)
{
int key = pbegin->key;
node *p = pbegin;
node *q = p->next;
while(q!=pend)
{
if(q->key<key)
{
p = p->next;
swap(p->key,q->key);
}
q=q->next;
}
swap(p->key,pbegin->key);
return p;
}
void quicksort(node *pbegin,node*pend)
{
if(pbegin != pend)
{
node *partion = getpartion(pbegin,pend);
quicksort(pbegin,partion);
quicksort(partion->next,pend);
}
}
使用时只需要调用quicksort(phead,nullptr);
2.归并排序
思想就是:首先找到链表的中点,然后分别对左边的链表和右边的链表进行归并排序。排序之后将两个有序链表进行合并。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(head == nullptr || head->next == nullptr)return head;
if(head->next->next == nullptr)
{
if(head->next->val<head->val)
{
swap(head->next->val,head->val);
}
return head;
}
ListNode *first = head;
ListNode *second = head;
while(first&&first->next)
{
first = first->next->next;
second = second->next;
}
ListNode *temp =second->next;
second->next = nullptr;
ListNode *left = sortList(head);
ListNode *right = sortList(temp);
ListNode *cur = new ListNode(0);
ListNode *res = cur;
while(left&&right)
{
if(left->val <right->val)
{
cur->next = left;
cur = cur->next;
left = left->next;
}
else
{
cur->next = right;
cur = cur->next;
right = right->next;
}
}
cur->next = left==nullptr?right:left;
return res->next;
}
};