遍历一次,找到倒数第 k 个结点(k从1开始)
sqlistsearchk.h
//输入一个链表,输出链表的倒数第k个结点
#pragma once
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include<windows.h>
typedef int DataType;
typedef struct ListNode {
DataType data;
struct ListNode *pNext;
}ListNode;
// 初始化
void ListInit(ListNode **ppFirst)
{
assert(ppFirst != NULL);
*ppFirst = NULL;
}
// 销毁
void ListDestroy(ListNode **ppFirst)
{
assert(ppFirst != NULL);
ListNode *pNode, *pNext;
pNode = *ppFirst;
while (pNode != NULL) {
pNext = pNode->pNext;
free(pNode);
pNode = pNext;
}
*ppFirst = NULL;
}
ListNode* FindKthToTail(ListNode* pFirst, unsigned int k){
//@2 用两个指针,先让第一个指针走k-1步,此时若第一个指针是最后一个节点,
// 那么第二个指针在的位置就是倒数第k个节点
if (pFirst == NULL || k <= 0) {
return NULL;
}
ListNode *point1 = pFirst;//第一个指针
ListNode *point2 = pFirst;//第二个指针
for (unsigned int i = 1; i< k; i++) {//第一个指针走k-1步
if (point1->pNext != NULL) {
point1 = point1->pNext;
}
else {//k大于链表的长度,找不到倒数第k个点
return NULL;
}
}
//此时两个指针一起运动
while (point1->pNext != NULL) {//直到第一个指针是最后一个节点
point1 = point1->pNext;
point2 = point2->pNext;
}
return point2;
}
ListNode * CreateNewNode(int data)
{
ListNode *pNewNode = (ListNode *)malloc(sizeof(ListNode));
assert(pNewNode);
pNewNode->data = data;
pNewNode->pNext = NULL;
return pNewNode;
}
// 尾插
void PushBack(ListNode **ppFirst, DataType data)
{
assert(ppFirst != NULL);
ListNode *pNewNode = CreateNewNode(data);
if (*ppFirst == NULL) {
*ppFirst = pNewNode;
return;
}
ListNode *pNode;
pNode = *ppFirst;
while (pNode->pNext != NULL) {
pNode = pNode->pNext;
}
// pNode 就是倒数第一个
pNode->pNext = pNewNode;
}
void Print(ListNode *pFirst)
{
ListNode *pNode;
for (pNode = pFirst; pNode; pNode = pNode->pNext) {
printf("%d -> ", pNode->data);
}
printf("NULL\n");
}
void TestSList()
{
ListNode *pFirst;
ListInit(&pFirst);
PushBack(&pFirst, 1);
PushBack(&pFirst, 2);
PushBack(&pFirst, 3);
Print(pFirst);
ListNode *pFound = FindKthToTail(pFirst, 2);
if (pFound == NULL) {
printf("没有找到\n");
}
else {
printf("%d\n", pFound->data);
}
ListDestroy(&pFirst);
}
//在牛客网的oj环境下编译通过的
//ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
// if (pListHead == NULL || k <= 0)
// return NULL;
// ListNode* pAhead = pListHead;
// for (int i = 1; i<k; i++){//让第一个指针pAhead先走k-1步
// if (pAhead->next != NULL)
// pAhead = pAhead->next;
// else
// return NULL;//此链表小于k个结点,找不到倒数第k个
// }
// ListNode *pBehind = pListHead;
// while (pAhead->next != NULL){两个指针一起走,如果第一个pAhead指针指向最后一个结点,即空节点的前一个,此时pBhead指向的就是倒数第k个结点
// pAhead = pAhead->next;
// pBehind = pBehind->next;
// }
// return pBehind;
//}
main.c
#include"sqlistsearchk.h"
//#include"complex.h"
//#include"mergeSlist.h"
int main()
{
TestSList();
//TestCN();
//Testmerge();
system("pause");
return 0;
}