想法一
先设置tail指针,在循环找尾的过程计数,最后得出节点数;再根据奇数和偶数判断,来找到中间节点
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* tail = head;
int count = 0;//节点数
while (tail)
{
tail = tail->next;
count++;
}
int i = 0;
if (count % 2 == 1)
{
for (i=0; i<(count-1)/2; i++)
{
head = head->next;
}
}
else
{
for (i=0; i<count/2; i++)
{
head = head->next;
}
}
return head;
}
想法二
如果要求只遍历一遍链表的过程中,找到中间节点,又应该怎么做呢?
我们可以设置slow和fast两个指针,slow每次走一个节点,fast每次走两个节点,这样,当fast走到尾部时,slow就来到了中间节点(该方法比较考验思维)
struct ListNode* middleNode(struct ListNode* head)
{
//要求只遍历一遍链表
struct ListNode* slow = head;//一次走一格
struct ListNode* fast = head;//一次走两格
while (fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (!fast)
{
break;
}
}
return slow;
}
注意:如果为偶数个节点时,fast会走到NULL,这时就要加上判断,提前跳出循环,防止对空指针进行解引用
以下是另一种表达方式,先判断fast是不是NULL,如果是,直接跳出循环,如果不是,才继续判断fast->next是不是NULL(&&的妙用)
struct ListNode* middleNode(struct ListNode* head)
{
//要求只遍历一遍链表
struct ListNode* slow = head;//一次走一格
struct ListNode* fast = head;//一次走两格
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}