148. Sort List
Sort a linked list in O(n log n) time using constant space complexity.
题意
对一个链表进行排序,要求时间复杂度O(nlogn),一般就是快排、归并、堆排序。这里选择归并排序
思路
分为两个步骤,一个步骤是拆分,直至都是单个结点,拆分使用了三个指针pre、slow、fast。slow走一步,fast走两步,当fast走到链表尾部时,slow指向的位置刚好是链表的中位数。这个时候链表分为[head…pre]和[slow…NULL],层层拆分,直至只有一个元素的时候,开始合并
另外一个步骤是合并(参考剑指offer p116),当两个链表不一样长的时候,需要做判断,返回长的一个链表。同时一直是节点值小的
代码
/**
* 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) {
//注意递归终止条件 当链表的元素小于2时,返回
if(!head||!head->next)
return head;
ListNode* pre = head, *slow = head, *fast = head;
while(fast&&fast->next)
{
pre = slow;
slow = slow->next;
fast = fast->next->next;
}
pre->next = NULL;
return MergeLink(sortList(head),sortList(slow));
}
ListNode* MergeLink(ListNode* head1, ListNode* head2)
{
if(!head1) //判断链表为空
return head2;
if(!head2)
return head1;
ListNode* pmerge = NULL;
if(head1->val < head2->val)
{
pmerge = head1;
pmerge->next = MergeLink(head1->next,head2);
}
else
{
pmerge = head2;
pmerge->next = MergeLink(head2->next,head1);
}
return pmerge;
}
};
147. Insertion Sort List
Sort a linked list using insertion sort.
思路
建立一个虚拟头结点,cur和next指针配合使用,永远指向已经排好序的链表,同时cur和next每经过一轮循环需要修正,cur需要移动到头结点位置,方便查找新节点在已排序的链表中的位置。
不断修正head,每次取一个头结点放到排序链表中做比较。核心代码
head->next = cur->next;
cur->next = head;
head = next;
代码
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
ListNode* newhead = new ListNode(-1);
ListNode* cur = newhead;
while(head)
{
ListNode* next = head->next;
cur = newhead;
while(cur->next && cur->next->val < head->val)
cur = cur->next;
head->next = cur->next;
cur->next = head;
head = next;
}
return newhead->next;
}
};