ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[HBU-实验]1-10 链表去重 (20 分)

2021-10-11 16:06:39  阅读:150  来源: 互联网

标签:Node 10 nextAddr node addr int 链表 memory HBU


题目描述

题目描述

测试

输入样例

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 data;
    string nextAddr;
    Node() : data(0),nextAddr(nullptr){};
};

int main(int argc, char const *argv[])
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    string firstNodeAddr;
    int N;

/*
00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854
*/
    cin >> firstNodeAddr >> N; //输入首地址和结点个数

    //地址和结点组成键值对
    map<string, Node> memory;
    for (int i = 0; i < N; i++)
    {
        string addr;
        Node *ptr = new Node;
        cin >> addr >> ptr->data >> ptr->nextAddr;
        memory[addr] = *ptr;
    }

    int nodeNum = 0;                    //计数,用于最后遍历输出
    vector<string> nodeAddrBeenDeleted; //存放被删除的结点的“地址”字符串(在map里能找)
    int nodeBeenDeletedNum = 0;         //被删除节点的个数

    set<int> bucket;                                //用集合存放已有的结点的数据
    bucket.insert(abs(memory[firstNodeAddr].data)); //先将第一个节点的数据放进去
    string addr = firstNodeAddr;
    Node *ptrPrev, *ptrCurrent;
    while (memory[addr].nextAddr != "-1")
    {                                                  //是否遍历到最后
        Node *ptrPrev = &memory[addr];                 //指向前一个结点的指针
        Node *ptrCurrent = &memory[ptrPrev->nextAddr]; //当前判断结点
        if (bucket.count(abs(ptrCurrent->data)) == 0)
        {                                         //若没有这个数据
            bucket.insert(abs(ptrCurrent->data)); //放到数据集合里
            addr = memory[addr].nextAddr;         //继续向下遍历
            nodeNum++;                            //保留结点数+1
        }
        else
        {                                                     //当前数据以有
            nodeAddrBeenDeleted.push_back(ptrPrev->nextAddr); //将当前地址放入被删除容器中
            ptrPrev->nextAddr = ptrCurrent->nextAddr;         //原链表中删除操作
            nodeBeenDeletedNum++;                             //被删除的结点个数+1
        }
        if (nodeNum + nodeBeenDeletedNum >= N)
            break;
    }

    addr = firstNodeAddr; //从第一个节点开始遍历
    //输出存留的链表
    for (int i = 0; i < nodeNum; i++)
    {
        Node *ptr = &memory[addr];
        cout << addr << " " << ptr->data << " " << ptr->nextAddr << endl;
        addr = memory[addr].nextAddr;
    }
    //最后一个单独处理
    cout << addr << " " << memory[addr].data << " -1" << endl;

    //“被删除结点”的链表更改next数据
    for (int i = 0; i < nodeAddrBeenDeleted.size() - 1; i++)
    {
        string addr = nodeAddrBeenDeleted[i];
        Node *ptr = &memory[addr];
        ptr->nextAddr = nodeAddrBeenDeleted[i + 1];
    }
    int n = 0;
    //输出被删除的链表
    for (string addr : nodeAddrBeenDeleted)
    {
        n++;
        Node *ptr = &memory[addr];
        if (n < nodeBeenDeletedNum)
        {
            cout << addr << " " << ptr->data << " " << ptr->nextAddr << endl;
        }
        else
        {
            cout << addr << " " << ptr->data << " -1" << endl;
        }
    }
    return 0;
}

算了我放弃了百度吧……
所以最后还是决定用数组写

如下代码,几个注意点:

  1. 结构体中一开始初始化num=2*Maxn,是先将其在排序时放到最后(因为可能会有数据不在链表上),在用链表遍历(一个个next时)遇到的才是在链表上的数据,更改其num即可
  2. num相当于记录的是其输出位置(用sort排序就将去重后的链表值放到了前面)
#include<bits/stdc++.h>
using namespace std;
#define Maxn 100000
struct Node{
    int pos,key,next,num=2*Maxn;  //没出现在链表中的直接放到最后
}node[Maxn];
int exist[Maxn];
bool cmp(Node a,Node b){
    return a.num < b.num;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int begin,N,a,cnt1=0,cnt2=0;
    cin >> begin >> N;
    for(int i=0;i<N;i++)
    {
        cin >> a;
        node[a].pos=a;
        cin >> node[a].key >> node[a].next;
    }
    for(int i=begin;i!=-1;i=node[i].next)
    {
        if(!exist[abs(node[i].key)])
        {
            exist[abs(node[i].key)] = 1;
            node[i].num = cnt1; 
            cnt1++;   //计数,相当于在所有数据中找前几个是要输出的
        }else{
            node[i].num = Maxn+cnt2; 
            //最后按num排序后则将不需要的结点放到后面,不输出
            cnt2++;   //标记的是不输出的数量
        }
    }
    sort(node,node+Maxn,cmp);
    int cnt = cnt1+cnt2;
    for(int i=0;i<cnt;i++)
    {
        cout<<setfill('0')<<setw(5)<<node[i].pos<<" "<<node[i].key<<" ";
        if(i!=cnt1-1 && i!=cnt-1)
            cout << setfill('0')<< setw(5) << node[i+1].pos << endl;
        else
            cout << -1 << endl;
    }
}

这里也是新学到两个函数

标签:Node,10,nextAddr,node,addr,int,链表,memory,HBU
来源: https://blog.csdn.net/yuri5151/article/details/120704825

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有