2019\] (15 分)已知一个带有表头节点的单链表,节点结构为
| data | link |
|------|------|
假设该链表只给出了头指针 `list`。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第 `k` 个位置上的结点(`k` 为正整数)。若查找成功,算法输出该节点的 `data` 域的值,并返回 1;否则,只返回 0。要求:
1)描述算法的基本思想;
2)描述算法的详细实现步骤;
3)根据设计思想和实现步骤,采用程序设计语言描述算法(使用 C、C++、或 Java 语言实现),关键之处请给出简要注释。
#### 1)算法基本思想
采用**双指针(快慢指针)法**,在不改变链表结构、仅遍历一次链表的前提下,高效找到倒数第 k 个结点:
* 定义两个指针 `fast` 和 `slow`,初始均指向表头节点。
* 先让 `fast` 指针向前移动 `k` 步,使两指针之间保持 `k` 个结点的距离。
* 之后 `fast` 和 `slow` 同时向后移动,当 `fast` 到达链表末尾时,`slow` 恰好指向倒数第 k 个结点。
* 若 `fast` 在移动 k 步的过程中提前到达末尾,说明 k 值超过链表长度,查找失败。
*** ** * ** ***
#### 2)详细实现步骤
1. **初始化** :定义指针 `fast`、`slow`,均指向链表头节点 `list`。
2. **前向移动 k 步** :循环移动 `fast` 指针,共 k 次;若循环中 `fast` 变为 `NULL`,说明 k 大于链表长度,返回 0。
3. **同步移动** :当 `fast` 不为空时,`fast` 和 `slow` 同时向后移动,直到 `fast` 指向链表尾节点的下一个位置(`NULL`)。
4. **结果处理** :此时 `slow` 指向倒数第 k 个结点,输出其 `data` 域值,返回 1;若步骤 2 中提前结束,返回 0。
*** ** * ** ***
#### 3)C 语言实现代码
核心代码
```cpp
// 链表结点结构定义(需在函数外声明)
typedef struct Node {
int data;
struct Node *link;
} Node;
// 核心函数:查找单链表倒数第k个结点
// 参数:list-链表头指针,k-倒数第k个位置
// 返回:查找成功返回1,失败返回0;成功时输出目标结点data值
int findKthFromEnd(Node *list, int k) {
// 1. 边界条件校验:空链表、k非正均直接失败
if (list == NULL || k <= 0) return 0;
// 2. 初始化快慢指针
Node *fast = list, *slow = list;
// 3. 快指针先移动k步,判断k是否超出链表长度
for (int i = 0; i < k; i++) {
if (fast == NULL) return 0; // k超过链表长度,返回失败
fast = fast->link;
}
// 4. 快慢指针同步移动,直到快指针到链表末尾
while (fast != NULL) {
fast = fast->link;
slow = slow->link;
}
// 5. 找到目标结点,输出data并返回成功
printf("%d\n", slow->data);
return 1;
}
```
完整代码
```cpp
#include
单链表应用:双指针【快慢指针】
Book思议-2026-03-17 12:35