【408算法】2009 单链表倒数第 k 个元素

178 阅读1分钟

题目

已知一个带有表头结点的单链表,结点结构为 |data|-|link| 假设该链表只给出了头指针 list, 在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第 k 个位置上的结点(k 为正整数).若查找成功,算法输出该结点的data值,并返回 1;否则只返回 0.

要求:

1)描述算法的基础设计思想

2)描述算法的详细实现步骤

核心算法(c++)

设 q 指向末尾第 k 个结点,那么当 k 小于等于链表长度时,q 为正数第 t 【n−(k−1)】个结点( 假设有 n 个结点 )。

先遍历一遍链表求出链表长度 n,再遍历一次链表找到第 t 个结点。

时间复杂度:O(n)

空间复杂度:O(1)

#include <cstdio>
#include <cstdlib>

typedef struct node{
    int data;
    struct node* link;
}NODE;

int ans(NODE* L, int k){
    // 获取总数量
    NODE * p = L->link;
    int t , n = 0;
    while(p != nullptr){
        n++;
        p = p->link;
    }

    // 计算获取顺取节点
    t = n - k + 1;
    if(t <= 0) {
        return 0;
    }
    p = L;
    while(t--) {
        p = p->link;
    }
        
    printf("%d\n", p->data);
    return 1;
}

// ========================以下为测试============================


//使用尾插法创建结点
void create(NODE* &L){
    NODE *r = L;
    for(int i = 2;i < 8;i++){
        NODE* s = (NODE*)malloc(sizeof(NODE));
        s->data = i;
        r->link = s;
        r = s;
    }
    r->link = nullptr;

}
//打印链表
void print(NODE* L){
    NODE* p = L->link;
    while(p!=nullptr){
        printf("%d ", p->data);
        p = p->link;
    }
}

int main(){
    // 初始化内存信息
    NODE *L = (NODE *) malloc(sizeof (NODE));
    L->link = nullptr;
    create(L);
    print(L);

    int k = 3;//倒数第k个元素
    printf("查询返回结果:%d", ans(L, k));

    return  0;
}