PTA 乙级 1025 反转链表

本文介绍了一种基于链表的数据结构重构算法,通过读取初始链表数据并进行特定的排序和重组,实现了对链表中元素的重新组织。该算法首先读取链表的基本信息,然后按照指定的规则对链表进行切割和重新连接,最终输出重构后的链表结构。

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

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define X 100000

typedef struct
{
	int Address, Data, Next;
}LinkedList;

int main()
{
	LinkedList *a = (LinkedList*)malloc(sizeof(LinkedList) * X);
	int K, start_address, N;

	for (int i = 0; i < X; i++)a[i].Data = -1, a[i].Next = -1;
	scanf("%d %d %d", &start_address, &N, &K);
	if (K > N)K -= N;
	for (int i = 0; i < N; i++)
	{
		int address, data, next;

		scanf("%d %d %d", &address, &data, &next);
		a[address].Data = data, a[address].Next = next, a[address].Address = address;
	}

	LinkedList *b = (LinkedList*)malloc(sizeof(LinkedList)*N);
	int j = 0, count = 0;
	b[j++] = a[start_address];
	while (b[j - 1].Next != -1)b[j] = a[b[j - 1].Next], j++;
	count = j;
	
	LinkedList *c = (LinkedList*)malloc(sizeof(LinkedList)*N);
	int cnt = 0;
	for (int i = K - 1; i < count; i += K)
		for (int j = 0; j < K; j++)c[cnt++] = b[i - j];
	for (int i = cnt; i < count; i++)c[cnt++] = b[i];
	for (int i = 0; i < count; i++)
		if (i != count - 1)c[i].Next = c[i + 1].Address;
		else c[i].Next = -1;
	for (int i = 0; i < count; i++)
		if (i != count - 1)printf("%05d %d %05d\n", c[i].Address, c[i].Data, c[i].Next);
		else printf("%05d %d %d\n", c[i].Address, c[i].Data, c[i].Next);

	return 0;
}
### 实现思路 要实现 PTA Basic 1025 题目中的链表反转功能,可以按照以下逻辑设计 C 语言代码: 1. **读取输入数据**:解析输入的节点地址、节点总数 `N` 和反转步长 `K`。 2. **构建链表**:通过输入的数据创建一个单向链表。 3. **分段反转链表**:对于每一段长度为 `K` 的子链表执行反转操作。如果剩余部分不足 `K` 则保持原样。 4. **输出结果**:按要求顺序打印反转后的链表。 以下是完整的 C 语言实现代码及其解释: ```c #include <stdio.h> #include <stdlib.h> // 定义链表节点结构体 typedef struct Node { int address; int data; int next; } Node; int main() { int startAddress, N, K; scanf("%d %d %d", &startAddress, &N, &K); // 输入起始地址、节点数量和反转步长 Node nodes[100000]; // 创建最大容量的数组存储所有可能的节点 int addresses[N]; for (int i = 0; i < N; ++i) { // 初始化节点并记录其地址 int addr; scanf("%d", &addr); addresses[i] = addr; scanf("%d %d", &(nodes[addr].data), &(nodes[addr].next)); nodes[addr].address = addr; } // 构建链表序列 int currentAddr = startAddress; int count = 0; while (currentAddr != -1 && count < N) { addresses[count++] = currentAddr; currentAddr = nodes[currentAddr].next; } // 对链表进行分段反转 for (int i = 0; i < count; i += K) { if (count - i >= K) { // 如果当前段长度大于等于K则反转 for (int j = 0; j < K / 2; ++j) { int temp = addresses[i + j]; addresses[i + j] = addresses[i + K - 1 - j]; addresses[i + K - 1 - j] = temp; } } } // 输出结果 for (int i = 0; i < count - 1; ++i) { printf("%05d %d %05d\n", addresses[i], nodes[addresses[i]].data, addresses[i + 1]); } printf("%05d %d -1\n", addresses[count - 1], nodes[addresses[count - 1]].data); return 0; } ``` #### 关键点说明 - 使用了一个固定大小的数组来模拟所有的节点存储位置[^1]。 - 在处理链表时,先将其转换成线性数组以便于后续的操作[^2]。 - 当前算法的时间复杂度主要由两部分组成:一是遍历整个列表 O(N),二是局部翻转过程也是 O(N)[^3]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值