编写程序,要求通过一次遍历找到单链表中倒数第 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值