假设该链表只给出了头指针 list,在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数),若查找成功,算法输出该结点的data的值,并返回1;否则,只返回 0。用C语言表示
时间: 2024-10-09 19:04:24 浏览: 53
为了查找链表中倒数第 k 个节点的值,我们可以使用双指针策略。这里有一个简单的 C 语言算法:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
int findKthFromEnd(Node* list, int k) {
if (list == NULL || k <= 0) {
return 0; // 链表为空或 k 无效,直接返回 0
}
Node* slow_ptr = list; // 慢指针,每一步走一步
Node* fast_ptr = list; // 快指针,每一步走两步
// 让快指针先走 k 步
for (int i = 0; i < k; ++i) {
if (fast_ptr == NULL) {
return 0; // 如果快指针到达了链表尾部还没超过 k,则不存在倒数第 k 个节点
}
fast_ptr = fast_ptr->next;
}
while (fast_ptr != NULL) {
slow_ptr = slow_ptr->next;
fast_ptr = fast_ptr->next;
}
if (slow_ptr != NULL) {
printf("倒数第 %d 个节点的值为:%d\n", k, slow_ptr->data);
return 1;
} else {
return 0; // 指针已经到了链表尾部,但仍没找到倒数第 k 个节点
}
}
// 示例
Node* createList(int* arr, int size) {
Node* head = malloc(sizeof(Node));
head->data = arr[0];
head->next = NULL;
for (int i = 1; i < size; ++i) {
Node* newNode = malloc(sizeof(Node));
newNode->data = arr[i];
newNode->next = head->next;
head->next = newNode;
}
return head;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
int k = 2;
int size = sizeof(arr) / sizeof(arr[0]);
Node* list = createList(arr, size);
int result = findKthFromEnd(list, k);
free(list); // 别忘了释放内存
return 0;
}
```
这个算法的时间复杂度是 O(n),其中 n 是链表的长度,因为最多需要遍历整个链表两次(一次慢指针,一次定位到倒数第 k 个节点)。空间复杂度是 O(1),因为我们只用了常数级别的额外空间。
阅读全文