148.排序链表(C)

题目描述:

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

递归:

1、递归的三要素

   在我们了解了递归的基本思想及其数学模型之后,我们如何才能写出一个漂亮的递归程序呢?笔者认为主要是把握好如下三个方面:

1、明确递归终止条件;

2、给出递归终止时的处理办法;

3、提取重复的逻辑,缩小问题规模。

模型一: 在递去的过程中解决问题 

function recursion(大规模){
    if (end_condition){      // 明确的递归终止条件
        end;   // 简单情景
    }else{            // 在将问题转换为子问题的每一步,解决该步中剩余部分的问题
        solve;                // 递去
        recursion(小规模);     // 递到最深处后,不断地归来
    }
}

模型二: 在归来的过程中解决问题

function recursion(大规模){
    if (end_condition){      // 明确的递归终止条件
        end;   // 简单情景
    }else{            // 先将问题全部描述展开,再由尽头“返回”依次解决每步中剩余部分的问题
        recursion(小规模);     // 递去
        solve;                // 归来
    }
}

2、合并链表:

在归来的过程中解决问题:

/*

功能:mergeList 合并两个有序链表

入参:struct ListNode* left,struct ListNode* right,两个有序链表头结点

返回值:合并后的链表头结点

*/

struct ListNode* mergeList(struct ListNode* left,struct ListNode* right){
    if(left==NULL){// 明确的递归终止条件
        return right;
    }
    if(right==NULL){// 明确的递归终止条件
        return left;
    }

//在将问题转换为子问题的每一步,解决该步中剩余部分的问题
    if(left->val<right->val){
        left->next=mergeList(left->next,right); //递到最深处后,不断地归来
        return left;
    }
    else{
        right->next=mergeList(left,right->next); //递到最深处后,不断地归来
        return right;
    }
}

递去的过程中解决问题

/*

功能:merge 排序链表

入参:struct ListNode* node 链表头结点

返回值:合并后的链表头结点

*/

struct ListNode* merge(struct ListNode* node){
    if(node==NULL || node->next==NULL){     //明确的终止条件
        return node;          //简单场景
    }

// 先将问题全部描述展开,再由尽头“返回”依次解决每步中剩余部分的问题
    struct ListNode* slow=node,*fast=node->next;
    while(fast && fast->next){
        slow=slow->next;
        fast=fast->next->next;
    }
    struct ListNode* pre=slow->next;
    slow->next=NULL;     
    struct ListNode* l=merge(node);  // 递去 --缩小规模
    struct ListNode* r=merge(pre);    // 递去 --缩小规模
    return mergeList(l,r);  //归来中解决问题
}

struct ListNode* sortList(struct ListNode* head){
    return head==NULL?head:merge(head);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值