问题:
链表排序,从小到大。
参考链接:
1、
148_Sort List | O(nlogn)链表排序 | Medium
2、
Sort List
3、
4、
思想:排序算法中,自底向上的归并排序算法更适合链表排序(参考《算法》(第四版))。结合234. Palindrome Linked List中的寻找链表中间节点程序以及21. Merge Two Sorted Lists合并两个有序链表的程序。
注意点:
边界条件:空链表,1个节点的链表,2个节点的链表,3个节点的链表。
区别一下程序:
1、
ListNode* p=head;
ListNode* q=head;
//两个指针法实现从中间切分
while(q) //始终剩三个节点的链接不能排序
{
q = q->next;
if(q)
{
q = q->next;
}
p = p->next;
}
2、
while (q != nullptr && q->next != nullptr)
{
p = p->next;
q = q->next->next;
}
3、
while(q->next != NULL)
{
q = q->next->next;
if(q == NULL)
{
break;
}
p = p->next;
}
递归与归并过程如下:
代码:
/**
* 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;
//两个指针法实现从中间切分
/*
while(q) //始终剩三个节点的链接不能排序
{
q = q->next;
if(q)
{
q = q->next;
}
p = p->next;
} */
/*
while (q != nullptr && q->next != nullptr)
{
p = p->next;
q = q->next->next;
}*/
while(q->next != NULL)
{
q = q->next->next;
if(q == NULL)
{
break;
}
p = p->next;
}
ListNode* later = p->next;
p->next = NULL;
ListNode* left = sortList(head);
later = sortList(later);
return mergeTwoLists(left, later);
}
private:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(-1);
ListNode* tmp = head;
if (!l1) return l2;
if (!l2) return l1;
while(l1&&l2)
{
if(l1->val > l2->val)
{
tmp->next = l2;
l2 = l2->next;
}
else
{
tmp->next = l1;
l1 = l1->next;
}
tmp=tmp->next;
}
while(!l1&&l2)
{
tmp->next = l2;
l2 = l2->next;
tmp=tmp->next;
}
while(l1&&!l2)
{
tmp->next = l1;
l1= l1->next;
tmp=tmp->next;//跳到下一个位置
}
return head->next;
}
};