数据结构面试题------遍历一次,找到倒数第 k 个结点(k从1开始)

 遍历一次,找到倒数第 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;

}

猜你喜欢

转载自blog.csdn.net/pigdwh/article/details/81455050