pta重排链表

 本文提供pta重排链表的两种方法,两种都是使用数组模拟链表的操作,区别在与所使用空间的大小不同,从而导致时间复杂度也不同。

重排链表的第一种方法:

这种方法节省了很多空间,但在N非常大时会超时。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct Node* List;
struct Node {
	int Data;
	int Adr;
	int Next;
};

int main() {
	int FAdr, n, i, j;
	scanf("%d %d", &FAdr, &n);
	List L1;
	L1 = (List)malloc(n * sizeof(struct Node));
	int* a;
	a = (int*)malloc(n * sizeof(int));
	for (i = 0; i < n; i++) {
		scanf("%d %d %d", &L1[i].Adr, &L1[i].Data, &L1[i].Next);
		if (L1[i].Adr == FAdr) {
			a[0] = i;
		}
	}
	for (i = 1; i < n && L1[a[i - 1]].Next != -1; i++) {
		for (j = 0; j < n; j++) {
			if (L1[a[i - 1]].Next == L1[j].Adr) {
				a[i] = j;
				break;
			}

		}
	}
	if (i < n) n = i;
	for (i = 0; i < n / 2; i++) {
		printf("%05d %d %05d\n", L1[a[n - 1 - i]].Adr, L1[a[n - 1 - i]].Data, L1[a[i]].Adr);
		if (i == n / 2 - 1 && n % 2 == 0)
			printf("%05d %d %d\n", L1[a[i]].Adr, L1[a[i]].Data, -1);
		else
			printf("%05d %d %05d\n", L1[a[i]].Adr, L1[a[i]].Data, L1[a[n - 2 - i]].Adr);
	}
	if (n % 2 == 1) printf("%05d %d %d\n", L1[a[n / 2]].Adr, L1[a[n / 2]].Data, -1);
	return 0;
}

第二种方法:使用数组模拟链表操作,占用较大空间但时间复杂度小。


#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct Node {
	int Data;
	int Adr;
	int Next;
}List;

List L[100000];
List Res[100000];

int main() {
	int FAdr, n, i, rnum;
	scanf("%d %d", &FAdr, &n);
	int Adr, Data, Next;

	for (i = 0; i < n; i++) {
		scanf("%d %d %d", &Adr, &Data, &Next);
		L[Adr].Adr = Adr;
		L[Adr].Data = Data;
		L[Adr].Next = Next;
	}
	Adr = FAdr;
	rnum = 0;
	while (Adr != -1) {
		Res[rnum].Adr = L[Adr].Adr;
		Res[rnum].Data = L[Adr].Data;
		Adr = L[Adr].Next;
		rnum++;
	}


	for (i = 0; i < rnum / 2; i++) {
		printf("%05d %d %05d\n", Res[rnum - 1 - i].Adr, Res[rnum - 1 - i].Data, Res[i].Adr);
		if (i == n / 2 - 1 && n % 2 == 0)
			printf("%05d %d %d\n", Res[i].Adr, Res[i].Data, -1);
		else
			printf("%05d %d %05d\n", Res[i].Adr, Res[i].Data, Res[rnum - 2 - i].Adr);
	}
	if (n % 2 == 1) printf("%05d %d %d\n", Res[rnum / 2].Adr, Res[rnum / 2].Data, -1);
	return 0;
}

 

### 关于重排链表的解题思路 对于给定的任务,即重新排列单链表 \( L_1 \rightarrow L_2 \rightarrow ... \rightarrow L_{n-1} \rightarrow L_n\) 成新的形式 \( L_n \rightarrow L_1 \rightarrow L_{n-1} \rightarrow L_2 \rightarrow... \),一种有效的方法是先将链表中的节点存入列表中以便随机访问,然后再根据新顺序重建链表[^4]。 具体实现上,可以创建一个辅助函数用于读取输入并构建初始链表。接着,遍历该链表并将所有节点保存到Python列表中。完成此过程后,依据指定模式调整这些节点之间的链接关系: ```python class ListNode: def __init__(self, value=0, next=None): self.value = value self.next = next def rearrange_linked_list(head): if not head or not head.next: return head nodes = [] current_node = head while current_node is not None: nodes.append(current_node) current_node = current_node.next new_head = nodes[-1] i, j = 0, len(nodes)-1 while i < j: temp_next_i = nodes[i].next temp_next_j = nodes[j].next nodes[j].next = nodes[i] if i + 1 == j: nodes[i].next = None else: nodes[i].next = nodes[j-1] i += 1 j -= 1 return new_head ``` 这种方法能够有效地处理大规模的数据集而不会超出时间限制,因为其复杂度主要取决于线性扫描整个链表以及后续O(n)时间内重组指针的操作[^3]。 为了进一步优化性能,在实际编程竞赛环境中还可以考虑使用更高效的数据结构或算法来减少不必要的内存分配和释放动作;同时注意边界条件如空链表或只有一个元素的情况下的正确行为[^1]。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Skyline_98

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值