PTA 7-2 链表去重

这篇博客介绍了如何解决链表中绝对值重复键值节点的去重问题,给出了C++代码实现。程序首先读取链表数据,然后通过遍历检查节点是否存在重复,将去重后的节点存储到新链表,并将被删除的节点另存。最后,输出处理后的链表和被删除的链表。示例中展示了具体的输入输出格式。

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

这道题目的原型是
7-2 链表去重

给定一个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。

输入在第一行给出 L 的第一个结点的地址和一个正整数 N(≤105,为结点总数)。一个结点的地址是非负的 5 位整数,空地址 NULL 用 -1 来表示(这句话很关键)

随后 N 行,每行按以下格式描述一个结点:

地址 键值 下一个结点

其中地址是该结点的地址,键值是绝对值不超过104的整数,下一个结点是下个结点的地址。
输出格式:

首先输出去重后的链表,然后输出被删除的链表。每个结点占一行,按输入的格式输出。

输入样例:

00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854

输出样例:

00100 21 23854
23854 -15 99999
99999 -7 -1
00000 -15 87654
87654 15 -1

结尾无空行

**#include <bits/stdc++.h>
using namespace std;
struct node {
	int date; 
	int next;
	int add;
};
node a[100010]; //主要用到的数组也是数据存储的地方
int a1[100010],a2[100010]; //分离后的存储地址的数组,存储元素地址的数组;
int flag[100010];   //去重数组
int n,m,address,cnt1,cnt2,copy1;
void read() {
	for (int i=0; i<n; i++) {
		scanf("%d",&address);
		scanf("%d%d",&a[address].date,&a[address].next);
		a[address].add = address;
	}
}
void check() {	
	for (int i=0; i<n; i++) {  
		if (m == -1){  //在这里我想了很久,做了很多次实验
						//最终发现,其实这个模拟的链表可以不完整,可以在中间就断开了
						//00010 2 00012
						//00012 7 00033
						//00033 6 -1
						//99999 8 66666
						//66666 9 22222
						这种情况挺致命的,所以要在这里判断掉,其余的就是中规中矩的写法了;
			break;
		}
		if (flag[abs(a[m].date)] != 0) {
			a2[cnt2++] = a[m].add;
		} else {
			flag[abs(a[m].date)] = 1;
			a1[cnt1++] = a[m].add;
		}
		m = a[m].next;	
	}
}
void display() {
	printf("%05d %d ",a1[0],a[a1[0]].date);
	for (int i=1; i<cnt1; i++) {
		printf("%05d\n",a1[i]);
		printf("%05d %d ",a1[i],a[a1[i]].date);
	}
	printf("-1\n");
	//这里面存在一个特判,要是没有分离出来,就是全部都不相同的情况就特殊考虑一下;
	if (cnt2) {
		printf("%05d %d ",a2[0],a[a2[0]].date);
		for (int i=1; i<cnt2; i++) {
			printf("%05d\n",a2[i]);
			printf("%05d %d ",a2[i],a[a2[i]].date);
		}
		printf("-1\n");
	}
}
int main() {
	scanf("%d%d",&m,&n);
	copy1 = m;
	read(); 
	check();
	display();
	return 0;
}**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值