【数据结构】课后作业——返回倒数第k个数

本文介绍了一种高效查找链表中倒数第k个元素的算法,通过设置双指针优化了遍历过程,实现了O(n)的时间复杂度。详细解析了算法设计思路,并提供了代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

P38.21

有n个整数存放到链表L中,返回倒数第k个元素。

(1)算法的基本设计思想

遍历一遍链表,得到链表元素总数,然后再次遍历得到倒数第k个元素。

(2)代码如下

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;
LinkList CreatListend(LinkList &L)
{
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	LNode *s, *r = L;
	scanf("%d", &x);
	while (x != 9999)
	{
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;
		scanf("%d", &x);
	}
	r->next = NULL;
	return L;
}
void main()
{
	int count;
	LinkList L;
	CreatListend(L);
	LNode *p = L->next;
	LNode *q = L->next;
	printf("输入要查找的倒数第几个数\n");
	scanf("%d", &count);
	int num = 0;
	while (p != NULL)
	{
		num++;
		p = p->next;
	}
	int _count = num - count + 1;
	if (_count <= 0)
	{
		printf("输入错误");
	}
	else
	{
		while (_count != 1)
		{
			q = q->next;
			_count--;
		}
		printf("倒数第%d个数为%d", count, q->data);
	}
}

(3)复杂度

时间复杂度O(n)

空间复杂度O(n)

较好的算法

(1)算法的基本设计思想

应该有这样一个事实,若想知道倒数的元素,则必须知道元素总数。那么,至少遍历一遍链表是必不可少的。之后最白痴的做法我已经在上面给出了,就是再遍历一次。这样,当查找最后一个元素的时候,情况是最糟的,需要遍历整整两次。为减少操作时间,需要优化的是第一次遍历之后的操作。第一次遍历是不可能避免的。

我们设两个指针p和q,p随着链表节点一个一个往下走,q则不动,知道p和q差距为k。那么,当p到达尾节点,q就是倒数第k个节点了。

这种算法的时间耗费仅仅是遍历一次,与上面算法最优的情况下相同。
要学习这种思想,这个算法还是不难想到的。

(2)代码

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;
LinkList CreatListend(LinkList &L)
{
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	LNode *s, *r = L;
	scanf("%d", &x);
	while (x != 9999)
	{
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;
		scanf("%d", &x);
	}
	r->next = NULL;
	return L;
}
void main()
{
	int count;
	LinkList L;
	CreatListend(L);
	LNode *p = L->next;
	LNode *q = L->next;
	printf("输入要查找的倒数第几个数\n");
	scanf("%d", &count);
	int num = 0;
	while (p != NULL)
	{
		num++;
		if (num <= count)
			p = p->next;
		else
		{
			p = p->next;
			q = q->next;
		}
	}
	printf("倒数第%d个数为%d", count, q->data);
}

(3)

时间复杂度O(n)

空间复杂度O(n)

人家能得满分,我只能得10分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值