1. 程式人生 > >編寫程式,要求通過一次遍歷找到單鏈表中倒數第 n 個節點

編寫程式,要求通過一次遍歷找到單鏈表中倒數第 n 個節點

這是我們實習的第一道題目

1問題描述:要求通過一次遍歷找到單鏈表中倒數第 個節點(ps: 不允許使用 雙向連結串列;不允許 修改原始單鏈表;可使用額外的輔助空間,但是輔助空間的數目必須最小,不能和 有關。)

儲存結構:採用鏈式儲存

結點定義

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 "stdafx.h"
#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