数据结构--线性链式表倒数第K项

本文介绍使用单向、双向链表解决求倒数第K个元素的问题,通过链表逆序创建简化求解过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://pintia.cn/problem-sets/910354764736491520/problems/910354975319912451(点击打开链接)

题目大意:给你一系列数,求倒数第k个数。
分析:一道思路题吧,虽然简单的数组就可以做,但学的毕竟是数据结构,还得用数组来做,一开始用的双向链表,写不出来,后来改成单向链表,卡在大数据上了。后来同学让帮忙找bug,看了人家的代码,用的是单向链表逆序创建,倒数第k个就成了正数第k个,不得不佩服啊!!!
代码:

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define ll long long

using namespace std;

typedef int Status;
typedef ll ElemType;
//随机大数据,改成ll才能过
typedef struct LNode
{
    ElemType data;
    int length;
    struct LNode *next;
} LNode,*LinkList;

Status Creat_L(LinkList &L);
Status Print_L(LinkList &L,int k,ElemType &e);

int main()
{
    LinkList L;
    L = (LNode*)malloc(sizeof(LNode));
    if(!L) exit(OVERFLOW);

    int k;
    scanf("%d",&k);

    Creat_L(L);

    ElemType res;
    Print_L(L,k,res);

    if(!res)
        cout << "NULL" << endl;
    else
        cout << res << endl;
}

Status Creat_L(LinkList &L)
{
    LNode *curPtr,*rearPtr;

    rearPtr = L;
    L -> length = 0;

    while(1)
    {
        curPtr = (LNode*)malloc(sizeof(LNode));
        if(!curPtr) exit(OVERFLOW);
        //原先用的int类型的,后来改成ll,但是这里忘改了,结果wa了一晚上。。。。。。
        scanf("%lld",&curPtr -> data);

        if((curPtr -> data) < 0)
        {
            rearPtr -> next = NULL;
            return OK;
        }
        else
        {
            curPtr -> next = NULL;
            rearPtr -> next = curPtr;
            rearPtr = curPtr;
            L -> length++;
        }
    }

}


Status Print_L(LinkList &L,int k,ElemType &e)
{
    if(k <= 0 || k > L -> length)
        return ERROR;

    int ans = 1;
    LNode *curPtr;
    curPtr = L -> next;

    while(ans < L -> length - k + 1)
    {
        curPtr = curPtr -> next;
        ans++;
    }

    e = curPtr -> data;

    return OK;
}
  • 用的单链表,输出倒数第k个,也就是输出正数第length - k + 1个,思路还不是自己想出来的。。。。。

和上面的思路差不多,但是这个给人一种更高大上的感觉,链表逆序创建。
代码:

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2
typedef int  Status;
typedef int ElemType;

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
    int length;
} LNode,*LinkList;

Status Creat_L(LinkList &L);
Status Print_L(LinkList &L,int k);

int main()
{
    LinkList L;
    int k;
    scanf("%d",&k);

    Creat_L(L);
    Print_L(L,k);
}

Status Creat_L(LinkList &L)
{
    L = (LNode*)malloc(sizeof (LNode));
    if(!L)  exit(OVERFLOW);

    LNode *curPtr,*rearPtr;
    rearPtr = L;
    L -> next = NULL;
    L -> length = 0;

    int m;
    while(scanf("%d",&m) && m >= 0)
    {
        curPtr = (LNode*)malloc(sizeof (LNode));
        if(!curPtr)  exit(OVERFLOW);
        //链表逆序创建
        curPtr -> data = m;
        curPtr -> next = L -> next;
        L -> next = curPtr;
        L -> length++;
    }
    return OK;
}

Status Print_L(LinkList &L,int k)
{
    if(k <= 0 || k > L -> length)
    {
        printf("NULL\n");
        return ERROR;
    }
    else
    {
        LNode *curPtr;
        curPtr = L -> next;
        int ans = 1;
        while(ans < k)
        {
            curPtr = curPtr -> next;
            ans++;
        }

        printf("%d\n",curPtr -> data);
        return OK;
    }
}

真的有必要和别人的代码进行比对啊!!!

双向链表也搞定了,嗯,真的要静下心来才可以,不然效率会更低的!!!!

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>

#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

using namespace std;

typedef int Status;
typedef int ElemType;

typedef struct LNode
{
    ElemType data;
    int length;
    struct LNode *prior,*next;
}LNode,*LinkList;

Status Creat_L(LinkList &L);
Status Print_L(LinkList &L,int k);

int main()
{
    LinkList L;
    L = (LNode*)malloc(sizeof(LNode));
    if(!L)  exit(OVERFLOW);

    int k;
    scanf("%d",&k);

    L -> next = NULL;
    L -> prior = NULL;

    Creat_L(L);

    Print_L(L,k);
}

Status Creat_L(LinkList &L)
{
    LNode *curPtr,*rearPtr;

    rearPtr = L;
    L -> length = 0;

    int m;
    while(scanf("%d",&m) && m >= 0)
    {
        curPtr = (LNode*)malloc(sizeof(LNode));
        if(!curPtr)
            exit(OVERFLOW);
        curPtr -> data = m;
        curPtr -> prior = rearPtr;
        curPtr -> next = NULL;
        rearPtr -> next = curPtr;
        rearPtr = curPtr;
        L -> length++;
    }

    rearPtr -> next = L;
    L -> prior = rearPtr;
    return OK;

}

Status Print_L(LinkList &L,int k)
{
    if(k <= 0 || k > L -> length)
    {
        printf("NULL\n");
        return OK;
    }

    int ans = 1;
    LNode *curPtr;
    curPtr = L -> prior;
    while(ans < k)
    {
        curPtr = curPtr -> prior;
        ans++;
    }

    printf("%d\n",curPtr -> data);
    return OK;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值