編寫程式,要求通過一次遍歷找到單鏈表中倒數第 n 個節點
這是我們實習的第一道題目
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到達連結串列末尾的時候
主要函式:
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