0 前言
最近刷leetcode时遇到了两道链表排序题,相对数组排序而言处理上复杂了一些,却蛮有意思。有必要记录一下。
1 插入排序
Leetcode第147题对链表进行插入排序并不复杂,相对于数组的插入排序来说思路是直接可以用的。首先我们设置一个dummy头节点,然后从待排序链表里依次拿出节点,放入dummy链表里的合适位置即可。p1和p2是用于寻找合适插入位置的两个指针。算法复杂度 o ( n 2 ) o(n^2) o(n2)。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head)
{
ListNode* dummy = new ListNode(INT_MIN);
while(head)
{
ListNode* p1 = dummy,*p2 = dummy->next,*tem = head;
head = head->next;
while(p2 != nullptr && p2->val <= tem->val)
{
p1 = p1->next;
p2 = p2->next;
}
p1->next = tem;
tem->next = p2;
}
return dummy->next;
}
};
2 归并排序
Leetcode第148题也是一道链表排序题,但是上一题的代码在此题不能通过,时间复杂度要求为 o ( n l o n g n ) o(nlongn) o(nlongn),所以需要归并排序。事实上同数组的归并排序相比,链表的归并排序要解决两个问题,一是如何找到链表的中点,二是如何让两个有序链表合并在一起。
对于第一个问题,可以使用快慢指针的做法。使用两个指针slow和fast初始化为头节点和头节点的下一个节点,每次让slow走一步,fast走两步,直到fast到达尾部。第二个问题请参考leetcode21题,这是一个基础问题,这里就不多赘述了。剩下的思路和数组归并排序差不多。
/**
* 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)
{
return mergeSort(head);
}
ListNode* mergeSort(ListNode* head)
{
if(head == nullptr || head->next == nullptr)
return head;
ListNode* slow = head,*fast = head->next;
while(fast != nullptr && fast->next != nullptr)
{
slow = slow->next;
fast = fast->next->next;
}
ListNode* tem = slow->next;
slow->next = nullptr;
ListNode* left = mergeSort(head);
ListNode* right = mergeSort(tem);
return merge(left,right);
}
ListNode* merge(ListNode* l1,ListNode* l2)
{
ListNode* dummy = new ListNode(0),*tail = dummy;
while(l1 && l2)
{
if(l1->val < l2->val)
{
tail->next = l1;
tail = tail->next;
l1 = l1->next;
}
else
{
tail->next = l2;
tail = tail->next;
l2 = l2->next;
}
}
if(l1)
tail->next = l1;
else
tail->next = l2;
ListNode* tem = dummy->next;
delete dummy;
return tem;
}
};