您的位置:首页 > 其它

Sort List

2014-04-21 16:31 316 查看
要求时间复杂度是O(nlogn),只能用归并,堆,快排。

而堆排序和快速排序都是基于交换的排序,对于链表结构并不合适。归并排序,在数组情况下,空间复杂度为O(N).

但在链表情况下,却可以用常量空间复杂度来实现。见Merge Two Sorted
Lists

归并排序思路在各种排序算法的比较已详细分析。

现在最主要的就是如何把链表分割成两部分。

采用slow-fast指针,slow走一步,fast走两步,当fast走到尾时,slow的前驱正好到链表的一半。在分割时,用pre记录slow的前驱。

实际上,这道题目与Merge k Sorted Lists类似,只不过把Lists换成了单个节点,更加简单了。

public ListNode sortList(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode slow = head;
ListNode fast = head;
ListNode pre = null;
while(fast!=null && fast.next!=null){
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
ListNode left = head;
ListNode right = pre.next;
pre.next=null;
ListNode leftNode = sortList(left);
ListNode rightNode = sortList(right);
return mergeTwoLists(leftNode,rightNode);
}

ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head = null;
if(l1 == null)return l2;
else if(l2 == null)return l1;
else{
if(l1.val < l2.val){
head = l1;
l1 = l1.next;
}else{
head = l2;
l2 = l2.next;
}
}
ListNode l3 = head;
while(l1!=null && l2!=null){
if(l1.val < l2.val){
l3.next =  l1;
l1 = l1.next;
}else{
l3.next =  l2;
l2 = l2.next;
}
l3=l3.next;
}
while(l1!=null){
l3.next =  l1;
l1 = l1.next;
l3=l3.next;
}
while(l2!=null){
l3.next =  l2;
l2 = l2.next;
l3=l3.next;
}
return head;
}

上述合并两个有序链表的程序中,因为要构造头结点,所以程序显得比较复杂,我们可以先构造一个头结点,最后再删除头结点也可以实现。

下面的代码是C++实现:

ListNode* sortList(ListNode* head) {
if(head == NULL || head->next == NULL)
{
return head;
}
ListNode* preslow = NULL;
ListNode* slow = head;
ListNode* fast = head;
while(fast != NULL && fast->next != NULL)
{
preslow = slow;
slow = slow->next;
fast = fast->next->next;
}
preslow->next = NULL;

ListNode* l1 = sortList(head);
ListNode* l2 = sortList(slow);

return mergeTwoSorted(l1, l2);
}

ListNode* mergeTwoSorted(ListNode* l1,ListNode* l2)
{
ListNode* l3 = new ListNode(0);//构造一个头结点
ListNode* head = l3;

while(l1!=NULL && l2!=NULL)
{
if(l1->val > l2->val)
{
l3->next = l2;
l2 = l2->next;
}
else
{
l3->next = l1;
l1 = l1->next;
}
l3 = l3->next;
}

if(l1 != NULL)
{
l3->next = l1;
}

if(l2 != NULL)
{
l3->next = l2;
}

ListNode* ret = head->next;
head->next = NULL;
delete head;
return ret;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: