单链表的面试题---找到链表的中间节点--找到链表的倒数第K个节点

第一题:找到单链表的中间节点(且时间复杂度为O(1))

快慢指针的方法:两个指针同时从头结点出发,快指针一次走2步,慢指针一次走1步,当快指针走完所有节点时,慢指针就恰好是该单链表的中间节点。(要注意单链表的长度是奇数还是偶数)

第二题:找到链表的倒数第K个节点(时间复杂度为O(1))

同样使用两个指针:让其中一个指针先走K步,然后让两个指针一起走。当先走的那个指针走完链表是,后出发的那个指针就是倒数第K个节点。倒数第K个节点也就是正数第单链表个数-K个节点。

下面是代码的实现:

LinkListTest.h文件

#pragma once

#define TextHeader printf("\n********************%s**********************\n",__FUNCTION

typedef char ElemType;
typedef struct LinkListT
{
	ElemType data;
	struct LinkListT* next;
}LinkListT;

LinkListT* head;

//初始化单链表
void LinkListT_Init(LinkListT** head);

//打印链表
void DisplayLinkListT(LinkListT* head);

//找到中间节点
LinkListT* FindMidNode(LinkListT* head); 

//尾插
LinkListT* LinkListT_PushBack(LinkListT** head,ElemType value);

// 找到倒数第 K 个节点. 
LinkListT* FindLastKNode(LinkListT* head, int K);

//创建一个节点
LinkListT* CreateNode(ElemType value);

LinkListTest.c文件

#include"LinkListTest.h"
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>

//初始化
void LinkListT_Init(LinkListT** head)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	*head = NULL;
}
//打印链表
void DisplayLinkListT(LinkListT* head)
{
	LinkListT* cur = head;
	if(head == NULL)
	{
		printf("空链表。\n");
		return;
	}
	for(cur = head;cur != NULL;cur = cur->next )
	{
		printf("【   %c:%p   】->",cur->data ,cur);
	}
	printf(" NULL ");
	printf("\n\n");
}

//创建节点
LinkListT* CreateNode(ElemType value)
{
	LinkListT* new_node = (LinkListT*)malloc(sizeof(LinkListT));
	new_node->data = value;
	new_node->next = NULL;
	return new_node;
}
//尾插
LinkListT* LinkListT_PushBack(LinkListT** head,ElemType value)
{
	LinkListT* cur = (*head);
	if(head == NULL)
	{
		//非法输入
		return NULL;
	}
	if((*head) == NULL)
	{
		*head = CreateNode(value);
		return *head;
	}
	while(cur->next != NULL)
	{
		cur = cur->next ;
	}
	cur->next = CreateNode(value);
	return cur->next;
}
//找到中间节点
LinkListT* FindMidNode(LinkListT* head)
{
	LinkListT* cur = head;
	LinkListT* mid = head;
	if(head == NULL || head->next == NULL)
	{
		//空链表
		return NULL;
	}
	while((cur->next != NULL)&&(cur->next ->next != NULL))
	{
		cur = cur->next->next ;
		mid = mid->next ;
	}
	return mid;
}
// 找到倒数第 K 个节点. 
LinkListT* FindLastKNode(LinkListT* head,int K)
{
	int c = 0;
	LinkListT* fast = head;
	LinkListT* slow = head;
	if(head == NULL )
	{
		//空链表
		return NULL;
	}
	if(K <= 0)
	{
		printf("输入错误.\n");
		return NULL;
	}
	for(c = 0;c < K-1;c++)
	{
		fast = fast->next ;
	}
	while(fast->next != NULL)
	{
		fast = fast->next ;
		slow = slow->next ;
	}
	return slow;
}
测试代码:
#include"LinkListTest.h"
#include<stdio.h>
void TEST_FindMidNode()
{
	LinkListT* ret = NULL;
	TextHeader;
	LinkListT_Init(&head);
	LinkListT_PushBack(&head,'l');
	LinkListT_PushBack(&head,'h');
	LinkListT_PushBack(&head,'e');
	LinkListT_PushBack(&head,'c');
	LinkListT_PushBack(&head,'b');
	LinkListT_PushBack(&head,'f');
	LinkListT_PushBack(&head,'n');
	DisplayLinkListT(head);
	ret = FindMidNode(head);
	printf("中间的节点是:【  %c:%p  】\n",ret->data ,ret);
}
void TEST_FindLastKNode()
{
	LinkListT* ret = NULL;
	TextHeader;
	LinkListT_Init(&head);
	LinkListT_PushBack(&head,'l');
	LinkListT_PushBack(&head,'h');
	LinkListT_PushBack(&head,'e');
	LinkListT_PushBack(&head,'c');
	LinkListT_PushBack(&head,'b');
	LinkListT_PushBack(&head,'f');
	LinkListT_PushBack(&head,'n');
	DisplayLinkListT(head);
    ret = FindLastKNode(head, 3); 
	printf("倒数第%d个节点是:【  %c:%p  】\n",3,ret->data);
}
int main()
{
	TEST_FindMidNode();
	TEST_FindLastKNode();
	return 0;
}

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值