ReOrder list 链表 重排序

本文详细介绍了单链表重组的基本思路及实现步骤,包括通过计算长度或快慢指针找到中点,反转后半部分链表,以及最终将两部分链表交错合并的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


关于单链表的题目,最重要的便是指针的操作。我近期涉及到的单链表的题目对我最大的感想就是:无论是对单链表的任何操作,一个单链表的标识便是它的头指针。所以很多的操作无非就是一个“新”的头节点带领着一列元素罢了。

对于上述的题目,可能刚开始的时候会无从下手,至少我是这样,我在考虑怎样将Ln移动到L1之后,怎样得到Ln-1的指针呢。其实分开来看,无非就是两个链表的merge, L = L0 , L1 , ...  L(n/2)  ;   R =  Ln, Ln-1, ... , L(n/2+1). 怎样得到这两个链表呢?

对于L, 直接截取链表的前 n/2 个元素即可。分为两种方法,

    1     首先计算整个链表的长度n, 然后 将头指针移动 n/2 次,便得到了 L:

    2  可以使用快慢指针的方式,快的指针每次移动两步,慢的指针每次移动一步,直到快的指针到达链表尾部时,此时的慢指针就是要找的分界点。


对于 R,由于在寻找L的过程中,将整个链表分成了前后断,后一段为 L(n/2+1), L (n/2+2), ... , Ln, 但是我们需要的R刚好是它的reverse。这里便涉及到链表的reverse的操作,其实很简单,只需要遍历一遍,将每个节点依次插入到 “新的” 链表的表头即可。

比如: L1,L2,L3 ,现要将这个链表reverse。设新的链表头为RR:

则RR = NULL;对于节点L1, 将L1插入到链表的表头,RR = L1,依次有 RR = L2,L1; RR = L3,L2,L1,

,因此达到了上述的reverse的目的。

最后一步直接merge L 和 R 即可。代码大致为:

    void reorderList(ListNode *head) {
        if(head == NULL) return;
        ListNode *tail = new ListNode(0);
        ListNode *t1 = head;
        int len = 0 ;
        while(t1)
        {
            len++;
            t1 = t1->next;
        }
        int mid = len/2;
        t1 = head;
        while(mid--) t1 = t1->next;
        ListNode *t2 = t1->next;
        t1->next = NULL;
        ListNode *t3 = NULL;
        //reverse
        while(t2)
        {
            t1 = tail->next;
            t3 = t2->next;
            tail->next = t2;
            t2->next = t1;
            t2 = t3;
        }
        
        t2 = tail->next;
        t1 = head;
        ListNode *t4 = NULL;
        while(t2)
        {
            t3 = t1->next;
            t4 = t2->next;
            t1->next = t2;
            t2->next = t3;
            t1 = t3;
            t2 = t4;
        }
        
    }

总结: 链表的操作主要是头节点的重要性。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值