两个思路:
思路一:把链表的值复制到一个数组里面去, 然后对这个数组排序,然后再把值复制回来原来的链表即可。
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head == nullptr)
return nullptr;
vector<int>res;
ListNode * p = head;
while( p )//把链表的值复制到数组里面去。
{
res.push_back (p -> val);
p = p->next;
}
sort(res.begin(), res.end());//排序
ListNode * pList = head;
//把数组的值复制回原来的链表。
for(int i = 0; i < res.size(); i++){
pList->val = res[i];
pList = pList->next;
}
return head;
}
};
思路二: 对链表进行归并排序。只不过在二分链表的时候和对普通的数组二分做法不一样。
设定一慢指针,快指针, 同时用pre记录慢指针的前驱节点。每一次快指针走两步,慢指针走一步,当快指针尾部指向空,即到链表的尾部的时候,可以把链表二分为两个链表了。不断的对链表进行二分,直到不能再分了,然后对链表进行合并排序。
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head == nullptr)
return nullptr;
if(head->next == nullptr)//一个节点不用排序了
return head;
ListNode * slow = head;//慢指针
ListNode * fast = head;//快指针
ListNode * pre = nullptr;//记录慢指针的前驱节点
while(fast && fast->next)//查找链表的中点
{
pre = slow;
slow = slow->next;
fast = fast->next->next;//快指针走两步
}
pre->next = nullptr;//把链表分成两部分
ListNode * left = sortList(head);//左边的链表二分
ListNode * right = sortList(slow);//对右边的链表二分
return merge(left, right);//合并排序
}
ListNode * merge(ListNode * p1, ListNode * p2)
{
if(p1 == nullptr)
return p2;
if(p2 == nullptr)
return p1;
if(p1->val <= p2->val)
{
p1->next = merge(p1->next, p2);//对剩余部分合并排序
return p1;
}
else
{
p2->next = merge(p1, p2->next);
return p2;
}
}
};