148. Sort List (归并) 和147. Insertion Sort List

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;        
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值