求链表的倒数第m个元素,看下面问题描述

如何设置两个指针和一个计数器,假设p和p1是指针,p2是计数器,P要遍历整个链表,那么,当p走过m的整数倍的时候,计数器P2清零,p1赋p的指针,p1是跳跃地向前进,当p走到头的时候呢,p1再走P2的计数个数。从而实现要求

你的逻辑是错误的,假设链表中一个12个元素,你要找倒数第5个,走过两轮之后,p走到末尾,p2计数是2,p1指向第10个元素,p1再走2次不也到头了吗,怎么会是你要的元素呢?
以你的逻辑的话,应该是p先走m步,用pt记录这个点,这时候p1不变,然后p再走m步,此时,让p1 等于pt,pt再次记录p的位置。当最后一次不足m步的时候,计数是p2,这时候,只需要让p1再走p2步,就是倒数第m个元素。
代码如下,如有帮助,请帮忙采纳一下,谢谢。

img

#include <stdio.h>
#include <stdlib.h>
struct StNode 
{
    int data;
    struct StNode* next;
};
//创建节点
struct StNode* CreateNode(int d)
{
    struct StNode* node = (struct StNode*)malloc(sizeof(struct StNode));;
    node->data = d;
    node->next = 0;
    return node;
}
//创建链表
struct StNode* CreateList()
{
    struct StNode* head,*p,*t;
    int data;
    head = 0;
    p = head;
    t = head;
    printf("创建链表,请输入链表数据:");;
    while(1)
    {
        scanf("%d",&data);
        t = CreateNode(data);
        if(head ==0)
        {
            head = t;
            p = head;
        }
        else
        {
            p->next = t;
            p = t;
        }
        if(getchar() == '\n') break;
    }
    return head;
}
//打印链表
void Display(struct StNode* head)
{
    while(head)
    {
        printf("%d ",head->data);
        head = head->next;
    }
    printf("\n");
}

struct StNode* GetNode(struct StNode* head,int m)
{
    struct StNode *p1=0,*pt = 0,*p;
    int i,cnt = 1;
    p = head;
    p1 = head;
    
    while (p)
    {
        if(cnt !=0 && cnt%m == 0)
        {
            if(pt!=0)
                p1 = pt;
            pt = p;
            cnt = 0;
            
        }
        cnt++;
        p = p->next;
    }
    
    if(pt==0) return 0; //说明链表长度不足m
    i=0;
    
    if(p1 == head) cnt--;
    while(i<cnt && p1)
    {
        i++;
        p1 = p1->next;
    }
    
    return p1;
}


int main()
{
    struct StNode* list1 = CreateList();
    
    //打印链表
    Display(list1);

    struct StNode* p = GetNode(list1,2);//倒数第2个
    if(p)
        printf("倒数第2个:%d\n",p->data);
    else
        printf("没有那么多数据\n");

    p = GetNode(list1,5);//倒数第5个 
    if(p)
        printf("倒数第5个:%d\n",p->data);
    else
        printf("没有那么多数据\n");

    p = GetNode(list1,8);//倒数第8个 
    if(p)
        printf("倒数第8个:%d\n",p->data);
    else
        printf("没有那么多数据\n");

    p = GetNode(list1,15);//倒数第15个
    if(p)
        printf("倒数第15个:%d\n",p->data);
    else
        printf("没有那么多数据\n");
    return 0;
}


好像有点疑问,p1应该指向p前一个m倍数的节点,而不是p1赋p的指针。如果p1赋值p,那p1岂不是一直跳着跟着p了。当p到尾部时,p1和p的距离不足m。
应该是当p指向p2计数为m的倍数时,记住该位置,然后p继续往前移动,遇到下一个p2为m倍数时,才把p1指向前一个记录的p位置。这样当p到尾部时,p1向前移动p2最后的值,那么p1与链表尾部的距离正好是m,输出p1的值就可以了

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632