时间复杂度要求O(nlogn),可用快排,归并排,堆排来实现。
1,快排。快排基于分治法,取中枢值pivot作划分partition,一趟partition()操作后,中枢值位置定,表中元素被中枢值一分为二,递归划分两子表。当然划分函数partition()很重要。
代码实现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *sortList(ListNode *head) {
return quickSort(head,NULL);
}
ListNode* quickSort(ListNode *head,ListNode *end){
if (head!=end){
ListNode* pivot = partion(head, end);//返回中枢值的指针
quickSort(head,pivot);
quickSort(pivot->next,end);
}
return head;
}
ListNode* partion(ListNode *head,ListNode *end){
int key = head->val;
ListNode *p = head;
ListNode *q = head->next;
while(q!=end){
if(q->val<key){
p = p->next;
swap(p,q);
}
q = q->next;
}
swap(head,p);
return p;
}
void swap(ListNode *p,ListNode *q){
int temp = p->val;
p->val = q->val;
q->val = temp;
}
};
2,归并排。
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(!head || !head->next){
return head;
}
ListNode *p = head;
ListNode *q = head->next;
while(q && q->next){//快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点
p = p->next;
q = q->next->next;
}
ListNode *r = sortList(p->next);
p->next = NULL;
ListNode *l = sortList(head);
return merge(l,r);
}
ListNode *merge(ListNode *left,ListNode *right){ //写出merge函数,即如何合并链表。
ListNode dummy(0); //创建结构体dummy(0)
ListNode *p = &dummy;
while(left && right){
if (left->val < right->val){
p->next = left;
left = left->next;
}else{
p->next = right;
right = right->next;
}
p = p->next;
}
if (left) p->next = left;
if (right) p->next = right;
return dummy.next;//结构体取属性
}
};