查找链表中倒数第k个结点

描述

 

利用单链表表示一个整数序列,请实现一个时间复杂度为O(n)、空间复杂度为O(1)的算法,通过一趟遍历在单链表中确定倒数第k个结点。

 

输入

多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为k。当n=0时输入结束。

输出

对于每组数据分别输出一行,输出每个链表的倒数第k个结点对应的数值。

输入样例 1 

7
5 2 3 4 50 100 70
3
5
20 30 10 4 5
5
0

输出样例 1

50
20

一个很奇妙的思路,同时也可以建立双向链表(不循环)从后往前操作输出,

这道题总体思路还是很多的。

 

//要具备快慢指针的思想
//为了提高难度,要求只遍历一次链表,即链表长度未知
#include<iostream>
using namespace std;
typedef struct LNode
{
    int data;                        //数据域
    struct LNode *next;                //指针域
}LNode,*LinkList;
void InitList(LinkList &L)            //注意引用&符号:形参变化,改变实参
{
      L=new LNode;                    //给指针L分配地址
    L->next=NULL;                    //处理头结点L的指针域
}
void Input(LinkList &L,int n)        //注意引用&符号:形参变化,改变实参
{
    LinkList p=L;                    //指针p指向L的尾结点
    while(n--)                        //尾插法
    {
        LinkList q=new LNode;        //定义新结点并分配地址
        cin>>q->data;                //输入数据
        q->next=NULL;                //处理新节点q的指针域
        p->next=q;                    //将新节点q插在尾结点p的后面
        p=q;                        //更新指针p,指向新的尾结点
    }
}
void Locate(LinkList L)                //定位倒数第K个结点            
{
    LinkList L1=L;                    //设置L1为快指针
    LinkList L2=L;                    //设置L2为慢指针
    int k;
    cin>>k;
    while(k--)                        //快指针L1比慢指针L2提前走K个结点
        L1=L1->next;            
    while(L1)                        //当L1走到尾结点,L2走到倒数第K个结点
    {
        L1=L1->next;                //L1往后走
        L2=L2->next;                //L2往后走
    }
    cout<<L2->data<<endl;            //输出倒数第K个结点    
}
int main()
{
    int n;
    while(cin>>n&&n!=0)
    {
        LinkList L;                    //定义:LinkList类型的指针
        InitList(L);                //创建:初始化,分配地址
        Input(L,n);                    //输入数据
        Locate(L);                    //定位倒数第K个结点并输出
    }
    return 0;
}

 

posted @ 2020-10-16 23:25  奕玑  阅读(347)  评论(0)    收藏  举报