L2-002 鏈表去重 (25 分)

給定一個帶整數鍵值的鏈表 L,你需要把其中絕對值重複的鍵值結點刪掉。即對每個鍵值 K,只有第一個絕對值等於 K 的結點被保留。同時,所有被刪除的結點須被保存在另一個鏈表上。例如給定 L 爲 21→-15→-15→-7→15,你需要輸出去重後的鏈表 21→-15→-7,還有被刪除的鏈表 -15→15。

輸入格式:

輸入在第一行給出 L 的第一個結點的地址和一個正整數 N(≤10​5​​,爲結點總數)。一個結點的地址是非負的 5 位整數,空地址 NULL 用 -1 來表示。

隨後 N 行,每行按以下格式描述一個結點:

地址 鍵值 下一個結點

其中地址是該結點的地址,鍵值是絕對值不超過10​4​​的整數,下一個結點是下個結點的地址。

輸出格式:

首先輸出去重後的鏈表,然後輸出被刪除的鏈表。每個結點佔一行,按輸入的格式輸出。

輸入樣例:

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

node保存了節點的基本信息,當前地址now, 節點的值val, 下一個地址next, nodes[i]則存儲地址i下的一個完整節點信息。

用next0保存節點的鏈式關係,遍歷整條鏈,將val絕對值相同的篩選出來,這樣得到兩條鏈。

爲了打印的時候重新建立鏈式關係,在打印v[i].next時,實際上每次打印的是容器中下一個元素的now,即v[i + 1].now,另外就是最後一個節點的next要設成-1。

#include<iostream>
#include<map>
#include<cmath>
#include<vector>
#include<cstdio>
using namespace std;
const int maxn = 1e6 + 10;
int vis[maxn], next0[maxn];
struct node {
  int now, val, next;
} nodes[maxn];
void print(vector<node> &v) {
  for (int i = 0; i < v.size(); i++) {
    printf("%05d %d ", v[i].now, v[i].val);
    if (i + 1 < v.size()) printf("%05d", v[i + 1].now);
    else printf("-1");
    if (i < v.size() - 1) printf("\n");
  }
}
int main() {
  vector<node> v;
  int head, num;
  cin >> head >> num;
  while (num--) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    next0[a] = c;
    nodes[a] = node {a, b, c};
  }
  vector<node> v1, v2;
  for (int i = head; i != -1; i = next0[i]) {
    if (!vis[abs(nodes[i].val)]) {
      v1.push_back(nodes[i]);
      vis[abs(nodes[i].val)] = 1;
    } else {
      v2.push_back(nodes[i]);
    }
  }
  print(v1);
  printf("\n");
  print(v2); 
  return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章