2021-03-02PAT甲级1097 Deduplication on a Linked List (25 分)思路

PAT甲级1097 Deduplication on a Linked List (25 分)思路

  1. 题意:给出一个链表的首地址和n(n个结点,其中不一定每个结点都属于此链表),接下去给出各个结点的首尾地址及结点的值,要求去掉这个链表中权值绝对值相同的重复的数据(只保留最开始出现的),输出去重后的链表和去掉的元素组成的新的链表,都须按原链表顺序输出。
  2. 思路:应用静态链表的知识,同时需要用到散列表知识和结构体排序
  3. step1:存入各个结点的信息,同时得到有效的链表,将有效的结点做标记。
  4. step2:创建一个散列表,初值都为零,用来记录此节点权值的绝对值之前是否出现过,接下去遍历整个链表。
  5. step3:当链表中元素满足题意时,validnum++,不满足题意(重复)时,emptynum++,对链表按照cmp的规则进行排序。
  6. step4:cmp规则的定义是对order小的先输出出来。在先前的标记中,有效结点的order标记为validnum,maxn+emptynum,无效结点标记为2*maxn。
  7. step5:输出。
    代码如下
#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
struct Node
{
    int addr,next,data;
    int order;
}node[maxn];
bool cmp(Node x,Node y)
{
    return x.order<y.order;
}
int s[100010]={0};
int main()
{
    for(int i=0;i<maxn;i++)
        node[i].order=2*maxn;
    int begin,n;
    int addr;
    scanf("%d%d",&begin,&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&addr);
        node[addr].addr=addr;
        scanf("%d%d",&node[addr].data,&node[addr].next);
    }
    int p=begin;
    int validnum=0,emptynum=0,count=0;
    while(p!=-1)
    {
        if(s[abs(node[p].data)]==0)
        {
            s[abs(node[p].data)]=1;
            node[p].order=validnum++;
        }
        else
            node[p].order=maxn+emptynum++;
        p=node[p].next;
        count++;
    }
    sort(node,node+maxn,cmp);
    if(count==0)
    {
        printf("-1\n");
    }
    else
    {
        for(int i=0;i<validnum;i++)
        {
            if(i==validnum-1)
                printf("%05d %d -1\n",node[i].addr,node[i].data);
            else
                printf("%05d %d %05d\n",node[i].addr,node[i].data,node[i+1].addr);
        }
        for(int i=validnum;i<count;i++)
        {
             if(i==count-1)
                printf("%05d %d -1\n",node[i].addr,node[i].data);
            else
                printf("%05d %d %05d\n",node[i].addr,node[i].data,node[i+1].addr);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值