您的位置:首页 > 其它

LeetCode OJ 之 Sort List (排序链表)

2014-11-21 10:45 447 查看

题目:

Sort a linked list in O(n log n)
time using constant space complexity.

排序一个链表,要求时间复杂度O(n log n),空间复杂度O(1).

思路:

单链表适合用归并排序,双链表适合用快速排序,本题单链表使用归并排序,调用合并已排序的两个链表”Merge Two Sorted Lists” 的代码。

数组的归并排序参看:http://blog.csdn.net/u012243115/article/details/40373689

合并两个已排序的链表参看:http://blog.csdn.net/u012243115/article/details/40870019

代码:

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//单链表适合用归并排序,双链表适合用快速排序,本题调用”Merge Two Sorted Lists” 的代码。
//合并两个已经排好序的链表
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2)
{
//l1为空,则返回l2,l2为空,则返回l1
if (l1 == NULL) return l2;
if (l2 == NULL) return l1;

//q结点记录链表的起始结点
ListNode q(-1);
ListNode *p=&q;

//循环判断l1和l2大小,小的链接到p后,循环结束条件是l1和l2之间有一个先遍历完
while(l1 != NULL && l2 != NULL)
{
if(l1->val <= l2->val)
{
p->next = l1;
l1 = l1->next;
}
else
{
p->next = l2;
l2 = l2->next;
}
p = p->next;
}
//如果l2先遍历完,把l1接到p后即可
if(l1)
{
p->next = l1;
}
if(l2)
{
p->next = l2;
}
//返回连接后链表的首结点,不是q,q不属于l1和l2,而是q->next
return q.next;
}
ListNode *sortList(ListNode *head)
{
//递归结束条件
if(head == NULL || head->next == NULL)
return head;
//找到链表中间结点,并断开,分成两个链表,递归调用sortList,即是归并排序的思想
ListNode *slow = head;
ListNode *fast = head;
while(fast->next != NULL && fast->next->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
//把两个链表分成两个链表,后一个链表的头结点为slow
fast = slow; //把slow暂时存在fast内
slow = slow->next;//后一个链表的头结点
fast->next = NULL;//把前一个链表的最后一个结点的next赋为null

//递归调用sortList
ListNode *n1 = sortList(head);
ListNode *n2 = sortList(slow);
return mergeTwoLists(n1,n2);
}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode