这是我们实习的第一道题目
1问题描述:要求通过一次遍历找到单链表中倒数第 n 个节点(ps: 不允许使用 双向链表;不允许 修改原始单链表;可使用额外的辅助空间,但是辅助空间的数目必须最小,不能和 n 有关。)
存储结构:采用链式存储
结点定义
struct iNode{
int data;
iNode * next;
iNode(iNode *ptr=NULL){next=ptr;}
iNode(const int val,iNode *ptr=NULL)
{
data=val;next=ptr;
}
算法思想:
这个问题是需要建立一个标尺,表示他们两个指针之间的距离是多少,比如我建立两个指针iNode * pfirst=head;iNode *psecond=head;他们俩相隔N意味着在pfirst到达链表末尾的时候,psecond指针指向我们想要的那个值的位置。但是中间要判断一下链表的长度是否满足大于标尺长度这个要求。如果不满足就不必再往下进行了。
主要函数:
iNode * GetNnode(iNode * head, int n)
{
iNode * pfirst=head;
iNode *psecond=head;
int counter;
//第1步:建立标尺,移动pfirst N步
for(counter=0; counter<n; counter++)
{
if(NULL == pfirst) break; // 此时pfirst->next无意义
pfirst=pfirst->next;
}
if(n != counter) //长度不够n,未找到倒数第n个节点
return NULL;
//第2步:保持距离让标尺向右移动,直到右端指向末尾,左端即结果
while(pfirst!=NULL) {
pfirst=pfirst->next;
psecond=psecond->next;
return psecond;
}
}
附加代码:
cpp:
#include<iostream>
using namespace std;
#include<fstream>
#include"1.h"
int _tmain(int argc, _TCHAR* argv[])
{
int a[1000];
for(int i=0;i<1000;i++){a[i]=rand()%1000;}
ofstream fout("name.txt");for(int i=0;i<1000;i++){fout<<a[i]<<' ';}fout.close();
list li;fstream fin("name.txt"); fin>>li;
cout<<"链表中数据排列顺序为:"<<li<<endl;
iNode *h=li.GetNnode(li.gethead(),200);
int m=h->data;cout<<"链表中倒数第200个元素是"<<m<<endl;
return 0;
}
头文件:
#pragma once
#ifndef _LINKH_
#define _LINKH_
#include<iostream>
using namespace std;
struct iNode{
int data;
iNode * next;
iNode(iNode *ptr=NULL){next=ptr;}
iNode(const int val,iNode *ptr=NULL)
{
data=val;next=ptr;
}
};
class list{
public:
iNode *head;
list(){head= new iNode;}
list(const int x){head=new iNode(x);}
iNode * gethead()const{return head;}
list(list &L){
int value;
iNode *srcptr=L.gethead();
iNode *destptr=head=new iNode;
while(srcptr->next!=NULL)
{
value=srcptr->next->data;
destptr->next=new iNode(value);
destptr=destptr->next;
srcptr=srcptr->next;
}
destptr->next=NULL;
}
friend ostream& operator << (ostream &out, list &L){
iNode *current = L.head->next;
while (current->next){
out << current->data << '\t';
current = current->next;
}
out << endl;
return out;
}
friend istream& operator >> (istream &in, list &L){
iNode *newNode, *last;
int val;
last = L.head;
while (!in.eof()){
in >> val;
newNode = new iNode(val);
last->next = newNode;
last = newNode;
}
last->next = NULL;
return in;
}
iNode * GetNnode(iNode * head, int n)
{
iNode * pfirst=head;
iNode *psecond=head;
int counter;
//第1步:建立标尺,移动pfirst N步
for(counter=0; counter<n; counter++)
{
if(NULL == pfirst) break; // 此时pfirst->next无意义
pfirst=pfirst->next;
}
if(n != counter) //长度不够n,未找到倒数第n个节点
return NULL;
//第2步:保持距离让标尺向右移动,直到右端指向末尾,左端即结果
while(pfirst!=NULL) {
pfirst=pfirst->next;
psecond=psecond->next;
return psecond;
}
}
};
#endif