在这里我们介绍一种简单的思路:
定义两个指针(fast和slow)都指向头结点,fast指针先走K-1次后slow指针再走,当fast->next==NULL的时候,slow指针指向的位置就是我们所要找的倒数第K个节点
为了便于理解我们画图示意:
在理解了思路后实现时还需要注意如下几个问题:
1.空指针的判断,当链表的头指针为空时,这属于非法输入,应该直接返回
2.当要查找倒数第K个结点,K=0时,因为链表节点是从1开始记数,输入0毫无意义,也应该直接返回
3.应该用while循环不断的让fast与slow移动,fast最先到达NULL,所以循环终止条件为fast->next==NULL
具体实现代码如下:
FindKthToTail.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"FindKthToTail.h"
void LinkListInit(LinkNode**head)
{
if (head == NULL)
{
return;
}
*head = NULL;
}
LinkNode* CreateNode(LinkNodeType value)
{
LinkNode*new_node = (LinkNode*)malloc(sizeof(LinkNode));
new_node->next = NULL;
new_node->date = value;
return new_node;
}
LinkNode* LinkListFindKthToTail(LinkNode*head, unsigned int k)
{
if (head == NULL||k==0)
{
return NULL;
}
LinkNode*fast = head;
LinkNode*slow = head;
for (unsigned i = 0; i < k - 1; i++)
{
if (fast->next != NULL)
{
fast = fast->next;
}
else
{
return NULL;
}
}
while (fast->next != NULL)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
void LinkListPushBack(LinkNode**head, LinkNodeType value)
{
if (head == NULL)
{
return;
}
if (*head == NULL)
{
* head = CreateNode(value);
return;
}
LinkNode*cur = *head;
while (cur->next != NULL)
{
cur = cur->next;
}
cur->next = CreateNode(value);
}
void TestFinkKth()
{
LinkNode*head;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkNode*result=LinkListFindKthToTail(&head, 2);
printf("result expected is c,actual is %c", result->date);
}
int main()
{
TestFinkKth();
system("pause");
return 0;
}
FindKthToTail.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef char LinkNodeType;
typedef struct LinkNode{
struct LinkNode*next;
LinkNodeType date;
}LinkNode;
void LinkListInit(LinkNode**head);
LinkNode*CreateNode(LinkNodeType value);
void LinkListPushBack(LinkNode**head, LinkNodeType value);
LinkNode* LinkListFindKthToTail(LinkNode*head, unsigned int k);