[小技巧] 链表的对半划分

本文详细解析了使用快慢指针技术确定链表中点的两种情况,无论是链表存在头结点还是首节点作为起点,都能准确找到中点位置。通过调整指针移动策略,可使慢指针停在中点或中点前一个位置,适用于不同场景的链表操作。

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

使用快慢指针,fast每走两步,slow走一步,当fast停下时,slow就应该停止在链表的中间。


情况一: 

当链表有头结点head时,

fast = head;
slow = head;
while(fast != NULL && fast->next != NULL){
    fast = fast->next->next;
    slow = slow->next;
}

当链表有奇数结点时,slow正好停在正中间;当链表有偶数结点时,slow停在(指向)中间左侧结点


情况二: 

当链表无头结点,只有首节点head时,

fast = head;
slow = head;
while(fast != NULL && fast->next != NULL){
    fast = fast->next->next;
    slow = slow->next;
}

当链表有奇数结点时,slow正好停在正中间;当链表有偶数结点是,slow停在中间右侧结点


情况一与情况二的联系(回过头来才发现代码是完全相同的):

情况二本质上就是将当前的首节点看作情况一中的头结点而不参与链表中结点数量的统计,因此若实际链表是偶数结点,则活跃链表为奇数结点,根据情况一的性质,slow将停留在活跃链表的正中间,在实际链表中即为中间右侧,当实际链表是奇数结点时同理。


在实际使用中往往需要将两个链表断开成两部分,此时slow直接指向中间结点的情况就难以处理,需要他指向中间节点的前一个比较好,如下所示:

if(head == NULL || head->next == NULL){ /*特殊处理*/}

fast = head->next->next;
slow = head;
while(fast != NULL && fast->next != NULL){
    fast = fast->next->next;
    slow = slow->next;
}

本质上就是fast比slow多走了一次,或是slow少走了一次,从而直观的有slow->next等于原本slow指向的位置。

但是要注意这种方法需要在一开始进行特殊处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值