今日内容稍后补全以下内容来自:https://blog.csdn.net/weixin_60702024/article/details/141307874
真题题目
已知一个带有表头结点的单链表,结点结构为
{[data][link]}
假设该链表只给出了头指针list
。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data域的值,并返回1;否则,只返回0。要求:
- 描述算法的基本设计思想。
- 描述算法的详细实现步骤。
- 根据设计思想和实现步骤,采用程序设计语言描述算法(使用C、C++或 Java语言实现),关键之处请给出简要注释。
(本文重点关注算法实现及思路分析,不含具体答题表述)
分析实现
对于本题,最直观的想法是通过遍历同时计数找到第n-k+1个结点并返回,但得到链表的长度还需要先进行一轮循环。
因此,可以对上述过程进行简化——定义快慢指针,先令快指针指向慢指针之后的第k个结点,再令快慢指针一起向后移动。这样当快指针指向最后一个结点后的NULL时,慢指针指向的就是目标结点。
#include <iostream>
using namespace std;
struct LNode {
int data;
LNode *link;
};
// 查找链表中倒数第k个元素
int findRek(LNode* list, int k){
LNode* fast=list->link, *slow=list->link;
// 通过分支语句,将fast移动和两指针共同移动的操作合并在一个循环中
while(fast != NULL){
fast = fast->link;
// k - fast还需要移动的步数
if(k>0){
k--;
}else{
slow = slow->link;
}
if(k>0){
// 查找失败
return 0;
}else{
// 查找成功
cout<<slow->data<<endl;
return 1;
}
}
}
总结
以上就是通过遍历找到单链表倒数第k个结点的实现,此处的实现用到了快慢指针的思想,快慢指针在对链表的一些基础操作中是十分常见的思想,需要多加练习,能够熟练使用。