题目如下:

在这里插入图片描述
这道题呢,这里我写出了两种解决办法,一种遍历链表来得出中间结点,一种通过快慢指针来得出中间结点

第一种:

遍历:

首先我们设置一个计数器count,来记录链表的长度,写一个函数来遍历链表,返回

count的一半的大小,即为这个链表的中间结点。(在代码的最前面,写一个typedef方便后续命名结构体)

 typedef struct ListNode ListNode; 
int lenl(ListNode* head)
 {
    ListNode* tail=head;
    int count=0;
    while(tail)
    {
        count++;
        tail=tail->next;
    }
    return count/2;
 }

我们获取了中间结点之后,我们只需要将头结点设置为这个中间结点就可以了

struct ListNode* middleNode(struct ListNode* head) {
    int len=lenl(head);
    while(len>0)
    {
        head=head->next;
        len--;
    }
    return head;

}

这里我们重点需要知道的是,while 的循环条件,len>=0还是len>0

分析;

如果我们循环条件为len>=0

这里,以我们的示例一为例来解释
在这里插入图片描述
首先,我们的 len 通过计算得知为 2 ,如果len>=0的话,那么

第一次循环 len = 2进入循环
此时head向前,到达2的位置

第二次循环 len=1进入循环
此时head向前,到达3的位置

第三次循环 len=0 进入循环
此时head向前,到达4的位置

我们来验证一下:
在这里插入图片描述
一旦我将循环的结束条件写为len>=0那么就会导致头结点多向前走一步,所以我们这里应该为len>0,改正后,我们再来提交一下。
在这里插入图片描述

OK,这样就过辣!

第一种方法大家可能很容易想到,但是第二种方法用途非常广泛,使用其的地方也特别多——快慢指针

先来根据一个小学公式:a=2c;
如果这里a代表了链表的总长度,那么c就代表链表长度的一半

链表分为空链表,奇数链表,偶数链表
在这里插入图片描述
题目规定,本题没有空链表的出现,所以我们这里只讨论奇数和偶数链表。
首先我们来看奇数链表。

上图,我们分析一下:

在这里插入图片描述

当我们的fast指针走到链表的最后一个元素,我们的slow指针刚好落在我们的中间结点上,此时我们的fast就不能再向前了,因为我们的fast的next已经是空了,我们如果还要继续向前的话,就会造成解引用空指针的情况发生,进而导致程序报错。

偶数链表:
在这里插入图片描述
当我们的fast指针走到NULL的时候,我们的slow指针刚好落在我们的中间结点上,此时我们的fast就不能再向前了,因为我们的fast已经是空了,我们如果还要继续向前的话,就会造成解引用空指针的情况发生,进而导致程序报错。

下来我们具体的写一下代码:

struct ListNode* middleNode(struct ListNode* head) {
    ListNode* slow=head;
    ListNode* fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

我们在这里需要注意的是,我们的循环条件一定是fast&&fast->next
原因:如果我们先判断fast->next,当链表是一个偶数链表的时候fast自身已经为空了,无法解引用,会导致程序报错,所以,我们这里应该首先判断fast为不为空,顺序不能交换。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部