使用快慢指针,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指向的位置。
但是要注意这种方法需要在一开始进行特殊处理。