PAT-链表-A1097 Deduplication on a Linked List

题意:给出N个结点的地址address、数据域data以及指针域next,然后给出链表的首地址,要求去除链表上权值的绝对值相同的结点(只保留第一个),之后把未删除的结点按链表连接顺序输出,接着把被删除的结点也按在原链表中的顺序输出。

样例:原链表为21→-15→-15→-7→15,去除权值的绝对值相同的结点后的链表为21→-15→7,被删除的部分为-15→15。

思路:

  1. 使用静态链表存储节点,并设置一个数组来记录节点的绝对值。
  2. 遍历链表,借助标记数组来获取未删除的节点数和要删除的节点数。
  3. 依据题意对结果进行输出。

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100000;

struct Node
{
	//节点地址、值、下一个节点的地址、节点顺序
	int address, key, next, order;

	Node(int a=0,int k=0,int n=0,int o=2*maxn):address(a),key(k),next(n),order(o){}
};

bool cmp(Node A,Node B)
{
	return A.order < B.order;
}

//存储节点的静态链表、标记数组
Node datas[maxn];
bool recode[maxn] = { false };

int main()
{
	int first, num,keep_count = 0, invaild_count = 0;

	scanf("%d %d", &first, &num);

	//读入数据
	for (int i = 0;i < num;i++)
	{
		int a;

		scanf("%d", &a);
		scanf("%d %d", &datas[a].key, &datas[a].next);
		datas[a].address = a;
	}

	//遍历链表
	while (first != -1)
	{
		//由标记数组进行标记
		if (!recode[abs(datas[first].key)])
		{
			datas[first].order = keep_count++;
			recode[abs(datas[first].key)] = true;
		}
		else
		{
			//将要删除节点的顺序想后移,比保留的节点大,比无效节点小
			datas[first].order = maxn + invaild_count++;
		}
		first = datas[first].next;
	}

	sort(datas, datas + maxn, cmp);

	//按要求进行输出
	int count = keep_count + invaild_count;
	for (int i = 0;i < count;i++)
	{
		if (i == keep_count -1 || i==count-1)printf("%05d %d -1\n", datas[i].address, datas[i].key);
		else printf("%05d %d %05d\n", datas[i].address, datas[i].key, datas[i+1].address);
	}

	return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值