6-8 求链表的倒数第m个元素 (20 分)

请设计时间和空间上都尽可能高效的算法,在不改变链表的前提下,求链式存储的线性表的倒数第m(>0)个元素。

函数接口定义:

ElementType Find( List L, int m );

其中List结构定义如下:

typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /* 存储结点数据 */
    PtrToNode   Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

L是给定的带头结点的单链表;函数Find要将L的倒数第m个元素返回,并不改变原链表。如果这样的元素不存在,则返回一个错误标志ERROR

裁判测试程序样例:

#include 
#include 

#define ERROR -1

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表 */

ElementType Find( List L, int m );

int main()
{
    List L;
    int m;
    L = Read();
    scanf("%d", &m);
    printf("%d\n", Find(L,m));
    Print(L);
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

5
1 2 4 5 6
3

结尾无空行

输出样例:

4
1 2 4 5 6 

结尾无空行

这里我用了两种方法,先来看第一种

一、把所有的数存入数组后再来找倒数第m的数

ElementType Find( List L, int m ){
    int num[100000];//这里数组范围得大,不然会出现段错误,因为链表不是静态定义空间的
    int i=0;
    L=L->Next;//使他指向第一个节点
    while(L){
        num[i] = L->Data;//将数据存储到数组
        L = L->Next;
        i++;
    }
    if(m>i)
        return ERROR;
    else
        return num[i-m];
    
}

但是后来又询问了一位编程大神,这样简单的题真的不好意思去问,但他还是给我指了一条明路

二、

1、定义两个指针同时指向头指针(假设为L1和L2)

2、其中一个指针(设L1)先走,指向m

3、接下来同时前进,这样因为L1和L2之间相隔的距离是固定的,也就是末尾和倒数第m个元素相隔的距离。当L2走完时,L1指向的也就是我们所要寻找的元素。

ElementType Find( List L, int m ){
    List L1,L2;
    L1=L->Next;
    L2=L->Next;
    int i;
    for(i = 0;i < m;i++){
        if(L1==NULL){
            return ERROR;
        }
        L1=L1->Next;
    }
    while(L1){
        L1=L1->Next;
        L2=L2->Next;
    }
    return L2->Data;
}

你可能感兴趣的:(数据结构,list,链表,c语言)