链表不像顺序结构的数组那般可通过指定的下标访问中间值,我们通过指定一个快指针(步长为2,指针每次往下移动两位),一个慢指针(步长为1,指针每次往下移动一位),当快指针遍历完整个链表时,慢指针刚好指向链表的中间元素,以此原理,我们也能找到链表中的其他结点。
原理: 这就类似时间相同,速度和路程成正比,快指针的速度是慢指针的两倍,当快指针走完全程(单位1)时,慢指针刚好走到全程的1/2
图片描述:
为了防止空指针异常,以及当链表个数是偶数,该方法也适用,我们在遍历快指针时加上了一个安全验证,快指针本身不为空,fast!=null。
public static Node getMid(Node first){
Node fast=first;
Node slow=first;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
测试代码:
public class FastSlowTest {
public static void main(String[] args) {
Node first=new Node("aa",null);
Node second=new Node("bb",null);
Node third=new Node("cc",null);
Node fourth=new Node("dd",null);
Node fifth=new Node("ee",null);
Node sixth=new Node("ff",null);
Node seventh=new Node("gg",null);
Node eighth=new Node("hh",null);
first.next=second;
second.next=third;
third.next=fourth;
fourth.next=fifth;
fifth.next=sixth;
sixth.next=seventh;
seventh.next=eighth;
Node mid = getMid(first);
System.out.println("中间的结点是"+mid.item);
}
public static Node getMid(Node first){
Node fast=first;
Node slow=first;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
private static class Node<T>{
T item;
Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
}
|