You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单链表双指针法查找中间节点无输出的错误排查与修正

单链表双指针法找中间节点的代码错误排查与修正

问题说明

采用双指针法(指针q每次移动2个节点,指针p每次移动1个节点)查找单链表的中间节点,但程序仅能打印链表内容,无法输出中间节点的数据,代码如下:

#include <stdio.h>
#include <stdlib.h>

struct node{
    int data;
    struct node * next;
}*head=NULL;

void create(int A[],int n){
    struct node* last,*t;
    head=(struct node *)malloc(sizeof(struct node));
    head->data = A[0];
    head->next=NULL;
    last = head;
    
    for(int i=1;i<n;i++){
        t=(struct node *)malloc(sizeof(struct node));
        t->data = A[i];
        last->next=t;
        t->next = NULL;
        last= t;
    }
    
}
void display(struct node *p){
    while(p!=NULL){
        printf("%d ",p->data);
        p=p->next;
    }
}

void midofLL(){
    struct node *q,*p=head;
    while(q!=NULL){
        q=q->next;
        if(q) q=q->next;
        if(q) p=p->next;
    }
   printf("%d",p->data);
    
}

int main()
{
  int A[]={2,3,6,7,8};
  create(A,5);
  display(head);
  printf("\n");
  midofLL();
}

错误排查

核心错误是指针q未初始化:
在midofLL函数中,struct node *q,*p=head;仅对p做了初始化,q只是声明但未赋值,属于野指针。进入while(q!=NULL)循环时,q的初始值是随机的,大概率不为NULL,执行q=q->next会直接触发非法内存访问,程序崩溃,无法执行到打印中间节点的代码。

另外原循环逻辑存在冗余判断,且在链表长度为偶数时会导致p的位置偏移,不符合常规中间节点的预期。

修正方案

  1. 初始化指针q为head,和p保持相同起点;
  2. 调整循环条件为q != NULL && q->next != NULL,确保q每次移动两步时不会越界;
  3. 简化循环内逻辑,q每次移动两步,p每次移动一步,直到q无法继续移动。

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>

struct node{
    int data;
    struct node * next;
}*head=NULL;

void create(int A[],int n){
    struct node* last,*t;
    head=(struct node *)malloc(sizeof(struct node));
    head->data = A[0];
    head->next=NULL;
    last = head;
    
    for(int i=1;i<n;i++){
        t=(struct node *)malloc(sizeof(struct node));
        t->data = A[i];
        last->next=t;
        t->next = NULL;
        last= t;
    }
    
}
void display(struct node *p){
    while(p!=NULL){
        printf("%d ",p->data);
        p=p->next;
    }
}

void midofLL(){
    // 同时初始化q和p为head
    struct node *q=head,*p=head;
    // 循环条件确保q能安全移动两步
    while(q != NULL && q->next != NULL){
        q = q->next->next;
        p = p->next;
    }
    printf("中间节点数据:%d",p->data);
    
}

int main()
{
  int A[]={2,3,6,7,8};
  create(A,5);
  display(head);
  printf("\n");
  midofLL();
}

修正逻辑说明

  • 当链表长度为奇数(如示例中的5个节点):q最终会走到NULL,此时p停在第3个节点(正中间);
  • 当链表长度为偶数:q最终会走到最后一个节点的next(NULL),此时p停在中间偏左的节点(如4个节点时停在第2个),若需要中间偏右的节点,可将q初始化为head->next,循环条件不变。

内容的提问来源于stack exchange,提问作者Suba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:49:13