这道题的题目可以描述为:输入一个链表,输出该链表中倒数第k个结点。
本文中有关链表的结构体以及接口定义代码如下:
typedef int DataType;
typedef struct ListNode{
DataType data;
struct ListNode *next;
} ListNode;
//初始化
void ListInit(ListNode **ppfirst)
{
assert(ppfirst != NULL);
*ppfirst = NULL;
}
这道题的普通解题思路分为三步:
1.定义两个指针forward和backward,forward从链表头的头指针开始遍历向前走k-1步,backward保持不动;
2.从第k步开始,第二个指针backward也开始从链表的表头开始遍历;
3.由于两个指针之间的距离保持在k-1,当指针forward到达尾结点时,backward正好指向倒数第看个结点;
代码如下:
ListNode * FindTailK1(ListNode *first, int k)
{
ListNode *forward = first;
ListNode *backward = first;
while (k--)
{
forward = forward->next;
}
while (forward != NULL)
{
forward = forward->next;
backward = backward->next;
}
return backward;
}
同时我们应该注意到,在这个实现算法中,如果输入的K为0或输入的以forward为头结点的链表结点数小于K,都会导致程序奔溃。所以,针对这些问题对算法进行以下两点改进:
1.如果输入的k为0,直接返回NULL;
2.在第一个while循环中加一个if判断条件,如果输入的链表的节点数小于K,返回NULL;
代码如下:
ListNode * FindTailK2(ListNode *first, int k)
{
ListNode *forward = first;
ListNode *backward = first;
//k不为0
while (k == 0)
{
return NULL;
}
while (k--)
{
//结点数不小于k
if (forward->next != NULL)
{
forward = forward->next;
}
else
{
return NULL;
}
}
while (forward != NULL)
{
forward = forward->next;
backward = backward->next;
}
return backward;
}