您的位置:首页 > 其它

PTA试题_求单链表倒数第m个元素

2017-12-11 07:40 211 查看
题目叙述:

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


函数接口定义:

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 <stdio.h>
#include <stdlib.h>

#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个数是正数第几个。再从头遍历到倒数第m个数把它找出来

第二:设置两个指针,指针之间的距离为m。在拉开距离的过程中就可以排除掉m大于n的情况。拉开距离后,把当前指针从头遍历到尾,目标指针同步伐向后移动。

第一种方法:

ElementType Find( List L, int m ){

 if(m<=0)return ERROR;//确保输入的m是正数(下同)

 List h,p; //h用于保存L的头结点,p用于存放当前结点地址

 h=L;p=h->Next;

  int n=0,count;
  //n为链表长度,count为当前序数(用于和m作比较)

 ElementType D;
//D用于存放前一个比较元素

 while(p!=NULL){

   n++;

   p=p->Next;

  }

 n=n-m+1; //遍历结束,求出m的正数长度

 if(n<=0)return ERROR;

 p=h->Next;count=0;D=p->Data-1;

 while(p!=NULL)

  {

   if(D<p->Data)count++;

   if(count==n){

     return p->Data;

    }

   D=p->Data;

   p=p->Next;

  }

 return ERROR;

}

第二种方法:

ElementType Find( List L, int m ){

 if(m<=0)return ERROR;

 List previous=NULL,current=NULL;

 previous=current=L->Next;

  inti;

 for(i=1;i<=m;i++){

   if(current==NULL){

     return ERROR;

    }

   current=current->Next;

  }

 while(current!=NULL){

   current=current->Next;

   previous=previous->Next;

  }

 return previous->Data;

 

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: