1.归并排序递归版本
ListNode* sortList(ListNode* head) {
return mergesort(head);
}
ListNode* mergesort(ListNode* head)
{
if(head==NULL||head->next==NULL) return head;//这个地方要先判断head 再判断head->next
ListNode* fast=head;
ListNode* mid=head;
ListNode* pre=mid;
while(fast&&fast->next)
{
fast=fast->next->next;
pre=mid;
mid=mid->next;
}
pre->next=NULL;//关键点二
return merge(mergesort(head),mergesort(mid));
}
ListNode* merge(ListNode* head,ListNode* mid)
{
ListNode* res=new ListNode(-1);
ListNode* cur=res;
while(head&&mid)
{
if(head->val<mid->val)
{
res->next=head;
head=head->next;
}
else
{
res->next=mid;
mid=mid->next;
}
res=res->next;
}
if(head)
res->next=head;
if(mid)
res->next=mid;
return cur->next;
}
2.归并排序非递归
cut函数用来分割链表返回分割后的下一个节点,merge合并链表返回头结点。
(1)按照长度为1开始分割链表,然后合并两个链表,将他们链接起来,得到两两节点有序的链表;
(2)按照长度为2分割链表。。。。。重复上述过程。
ListNode* cut(ListNode* head,int n)
{
ListNode* p=head;
while(--n && p)
p=p->next;
if(p==nullptr)
return nullptr;
ListNode* suc=p->next;
p->next=nullptr;
return suc;
}
//迭代合并链表
ListNode* merge(ListNode* l1,ListNode* l2)
{
ListNode* dummy=new ListNode(0);
ListNode* p=dummy;
while(l1 && l2)
{
if(l1->val < l2->val)
{
p->next=l1;
l1=l1->next;
p=p->next;
}
else
{
p->next=l2;
l2=l2->next;
p=p->next;
}
}
p->next=l1 ? l1 : l2;
return dummy->next;
}
ListNode* sortList(ListNode* head)
{
if(head==nullptr || head->next==nullptr)
return head;
int length=0;
ListNode* p=head;
//先求得链表的长度,然后根据长度来cut
while(p)
{
length++;
p=p->next;
}
ListNode* dummy=new ListNode(0);
dummy->next=head;
for(int size=1;size<length;size*=2)
{
//cur表示待分割链表的第一个,tail表示已经合并好的链表的最后一个,类似于147题中的beign和tail
ListNode* cur=dummy->next;
ListNode* tail=dummy;
while(cur)
{
ListNode* left=cur;
ListNode* right=cut(left,size);
cur=cut(right,size);
tail->next=merge(left,right);
while(tail->next)
tail=tail->next;
}
}
return dummy->next;
}
3 快排递归
不交换节点值:
ListNode* quick_sort(ListNode* head, ListNode* end) {
if(head == nullptr) return end;
if(head->next == end) return head;
ListNode *l_head = nullptr, *l_end = nullptr;
ListNode *r_head = nullptr, *r_end = nullptr;
ListNode *p, *tmp = head->next;
while(tmp != end) {
p = tmp;
tmp = p->next;
if(p->val < head->val) {
if(l_end) {
l_end->next = p;
l_end = p;
}
else {
l_head = l_end = p;
}
}else {
if(r_end) {
r_end->next = p;
r_end = p;
}
else {
r_head = r_end = p;
}
}
}
if(l_end) l_end->next = head;//head左边都是比它小的节点
l_end = head;
if(r_end) r_end->next = end;
r_end = end;
l_head = quick_sort(l_head, l_end);
r_head = quick_sort(r_head, r_end);
head->next = r_head;
return l_head ? l_head : head;
}
ListNode* sortList(ListNode* head) {
return quick_sort(head, nullptr);
}
可以交换节点值:
ListNode* sortList(ListNode* head) {
linklistSort(head,NULL);
return head;
}
void linklistSort(ListNode* listBegin, ListNode* listEnd)
{
if(listBegin != listEnd)
{
ListNode* node = getPartion(listBegin,listEnd);
linklistSort(listBegin,node);
linklistSort(node->next,listEnd);
}
}
ListNode* getPartion(ListNode* phead, ListNode* pend)
{
int key = phead->val;
ListNode* p = phead;
ListNode* q = p->next;
while(q != pend)
{
if(q->val < key)
{
p = p->next;//p记录的是小于key的最后一个节点的位置
swap(p->val, q->val);
}
q = q->next;
}
swap(p->val, phead->val);
return p;
}