PTA题解 L2-002 链表去重(C++)

题目内容:

解题思路:

        本题主要是需要把一个链表按照一个标准分成两个链表,而这个标准就是该数的绝对值是否出现过,按照这个思路,我会给出我的解决办法。

        首先,设置一个结构体变量,便于后续链表数据存储。

        第一步,遍历链表,将 键值的绝对值 存入数组,之后每个元素内的键值在数组中遍历寻找,进行划分 留下 和 舍弃 的链表。

        第二步,若是键值没有出现过,将该元素存入留下的链表中,出现过则存入舍弃的链表中,将后继节点的坐标设为-1,即默认该元素为最后一位,同时将前一位的后继节点的坐标改为该元素的地址。

        对于第二步中的操作,可以将链表从数组的第二位开始存储,即可避免超出内存访问的问题。

        还有要注意,舍弃的链表是可以为空的。

C++代码展示:

#include <bits/stdc++.h>
using namespace std;

typedef struct fun { // 定义一个结构体fun,用于存储链表节点
    int ad;   // 地址
    int key;  // 关键字
    int next; // 下一个节点的地址
} ip;

int main() {
    int init, N; // 定义变量init(起始地址)和N(指令数量)
    vector<ip> s; // 定义一个向量s,用于存储指令
    int num[10005] = {0}; // 定义一个数组num,用于标记关键字是否出现过

    cin >> init >> N; // 读取起始地址和指令数量
    for (int i = 0; i < N; i++) {
        int a, b, c;
        cin >> a >> b >> c; // 读取每个指令的地址、关键字和下一个地址
        s.push_back({a, b, c}); // 将指令添加到向量s中
    }
    int p = init; // 设置初始地址为init
    ip liu[N+5], qi[N+5]; // 定义两个数组liu和qi,用于存储链表节点
    int t1 = 1, t2 = 1; // 初始化t1和t2,用于跟踪liu和qi数组的当前位置

    while (p != -1) { // 当当前地址p不是-1时继续循环
        for (int i = 0; i < N; i++) { // 遍历所有指令
            if (s[i].ad == p) { // 如果指令的地址与当前地址匹配
                if (num[abs(s[i].key)] == 1) { // 如果关键字已经出现过
                    qi[t2] = {s[i].ad, s[i].key, -1}; // 将指令添加到qi
                    qi[t2-1].next = qi[t2].ad; // 设置前一个节点的next指针
                    t2++; // 移动qi数组的指针
                } else { // 如果关键字未出现过
                    num[abs(s[i].key)] = 1; // 标记关键字为已出现
                    liu[t1] = {s[i].ad, s[i].key, -1}; // 将指令添加到liu
                    liu[t1-1].next = liu[t1].ad; // 设置前一个节点的next指针
                    t1++; // 移动liu数组的指针
                }
                p = s[i].next; // 更新当前地址为指令的下一个地址
            }
        }
    }

    // 打印liu链表
    int i = 1;
    for (i = 1; liu[i].next != -1; i++) {
        printf("%05d %d %05d\n", liu[i].ad, liu[i].key, liu[i].next);
    }
    printf("%05d %d -1\n", liu[i].ad, liu[i].key);

    // 打印qi链表
    for (i = 1; t2 != 1 && qi[i].next != -1; i++) {
        printf("%05d %d %05d\n", qi[i].ad, qi[i].key, qi[i].next);
    }
    if (t2 != 1) { // 如果qi链表不为空
        printf("%05d %d -1\n", qi[i].ad, qi[i].key, qi[i].next);
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值