【链表】单链表排序

知识点1:分治

分治即“分而治之”,“分“指的是将一大而复杂的问题划分成多人性质相同但是规模更小的子问题,子问题继续技照这样划分,直到问题可以被轻易解决,"治”指的是将子问题单独进行处理,经过分治后的子问题,需要将解进行合并才能得到原问题的解,因此整个分治过程经常用说归来实现。

知识点2: 双指针

双指针指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个指计(特殊情况甚至可以多个)》,两个指计或是同方向访问两个链表、或是同方向访问一个链表(快慢指针)、或是相反方向扫描(对撞指针),从而达到我们需要的目的。

具体做法:

1、首先判断链表为空或者只有一个元素,直接就是有序的

2、准备三个指针,快指right每次走两步,便指针mid每次走一步,前序指针ef每次跟在mid前一个位置。三个指针遍历链表,当快指针到达链表尾部的时候,慢指针mid刚好走了链表的一半,正好是中间位置

3、从left位置将链表断开,刚好分成两个子问题开始递归

4、将子问题得到的链表合并,参考合并两个有序链表

 

 

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */
 struct ListNode *merge(struct ListNode *head1, struct ListNode *head2)
 {
    if(head1 == NULL){
        return head2;
    }
    if(head2 == NULL){
        return head1;
    }

    //add list head
    struct ListNode head; 
    struct ListNode *cur = &head;

    while (head1 && head2) {
        if(head1->val <= head2->val){
            cur->next = head1;
            head1 = head1->next;
        }
        else{
            cur->next = head2;
            head2 = head2->next;
        }
        cur = cur->next;
    }

    if(head1){
        cur->next = head1;
    }
    else{
        cur->next = head2;
    }
    return head.next;


 }
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 the head node
 * @return ListNode类
 */
struct ListNode* sortInList(struct ListNode* head ) {
    // write code here
    //链表为空、只有一个元素,直接就是有序
    if(head == NULL || head->next == NULL){
        return head;
    }

    struct ListNode *left = head;
    struct ListNode *mid = head->next;
    struct ListNode *right = head->next->next;

    //右边指针到达末尾时,中间指针指向该段链表的中间
    while (right != NULL && right->next != NULL) {
        left = left->next;
        mid = mid->next;
        right = right->next->next;
    }
    //左边指针指向左端的左右一个节点,从这里断开
    left->next = NULL;
    //分成两段排序,合并有序的两端
    return merge(sortInList(head), sortInList(mid));

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值