链表的两大劣势就是无法快速访问某个元素和涉及链表的长度问题,但是有这么几个题就是专门针对这方面出的,例如:
一、链表的中间结点:
①奇数个结点的情况:
思路:slow每次走一步,fast每次走两步,相当于fast走完的时候slow只走了fast的一半也就是全程的一半。(slow先走,否则到不了中点)
②偶数个结点的情况
思路和奇数的一样,只不过返回的是第二个中间节点
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* slow = head, * fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
需要注意的是while循环的条件必须是这个顺序,否则写成这样的话会错误
while (fast->next && fast)
错误点:
①在结点为奇数时:fast已经到了最后一个结点,slow也到了中间结点,但由于while表达式先判断的是fast->next不为空,所以会继续往下走导致slow过头。
②在结点为偶数时:
在这种情况如果已经找到了目标结点,但是需要再进行循环判断,先判断的是fast->next那么此时就会造成空指针访问,但是如果换成正确写法的话就会先判断fast是否为空,“与”符号若是前面的表达式为false那么直接退出不会执行下一个表达式,所以也就没有非法访问的问题。