如何寻找单链表的中间结点?这里介绍两种方法。
1. 遍历 找到第 length/2 个结点
该方法的思路为:
(1) 先求解单链表的长度 length;
(2) 然后遍历 length/2 的距离即可查找到单链表的中间结点。
具体实现:
public Node findMidEle(Node head) {
int length = getLength(head);
Node tmp = head;
int len = 0;
if(length % 2 == 0) // 如果链表长度为偶数,有两个中间值,这里取前一个值作为中间值
len = length/2 - 1;
else // 链表长度为奇数时,只有一个中间值
len = length/2;
for(int i = 0; i < len; i++) {
tmp = tmp.next;
}
return tmp;
}
该方法的缺点:需要遍历两次链表,即第一次遍历求解单链表的长度,第二次遍历根据索引获取中间结点。
2. 双指针(快指针一次走两步,慢指针一次走一步)
如果是双链表。可以首尾并行,利用两个指针一个从头到尾遍历,一个从尾到头遍历,当两个指针相遇时,就找到了中间元素。以此思想为基础,如果是单链表,也可以采用双指针的方式来实现中间结点的快速查找。
该方法的思想为:
第一步,有两个指针同时从头开始遍历;
第二步,一个快指针一次走两步,一个慢指针一次走一步;
第三步,快指针先到链表尾部,而慢指针则恰好到达链表中部。
具体实现代码如下:
public Node searchMid(Node head) {
Node p = head;
Node q = head;
while(p != null && p.next != null && p.next.next != null ) {
p = p.next.next;
q = q.next;
}
return q;
}
快指针到链表尾部时,慢指针指向的结点和慢指针指向结点的下一个结点都是链表的中间结点。