题目
题目详解
就是一个静态链表删除元素的数据结构类型题目,这题最坑的地方在于输出的时候需要地址五位数补0,如果是-1则不用补,导致你明明是对的,还以为是错误的。。🤷♂️
- 我用队列存储删除的结点的地址,然后后面再进行连接即可。
解题代码
基本变量
int head, rm_head = -1; //分别用于存储两个链表的头结点地址
int N;
struct node {
int val;
int next;
node() : val(0), next(-1) {}
} linklist[MaxN];
queue<int> St; //存储被删除结点的地址
bitset<MaxN> check(0); //用于查重 Input函数
//输入和构建链表
void Input() {
scanf("%d%d", &head, &N);
int c = N;
while (c--) {
int addr, val, next;
scanf("%d%d%d", &addr, &val, &next);
linklist[addr].val = val;
linklist[addr].next = next;
}
} handle函数
//处理链表的去重问题
void handle() {
//正常删除链表结点的处理方式
int pre = head;
check[abs(linklist[head].val)] = 1;
for (int i = linklist[pre].next; i != -1; i = linklist[i].next) {
int val = abs(linklist[i].val);
if (!check[val]) {
check[val] = 1;
pre = i;
}//一旦出现重复结点,把这个结点删除就行,删除结点的操作需要双指针辅助
else {
linklist[pre].next = linklist[i].next;
St.push(i);
}
}
if (St.empty())
return;
//根据队列进行正确连接
int num = St.front();
St.pop();
rm_head = num;
while (!St.empty()) {
linklist[num].next = St.front();
num = linklist[num].next;
St.pop();
}
linklist[num].next = -1;
} print函数
//打印链表即可---注意小坑--(地址打印五位数字,少了补0,-1时不能打印五位数)
void print() {
handle();
for (int i = head; i != -1; i = linklist[i].next) {
if (linklist[i].next != -1)
printf("%05d %d %05d\n", i, linklist[i].val, linklist[i].next);
else {
printf("%05d %d %d", i, linklist[i].val, linklist[i].next);
}
}
if (rm_head == -1)
return;
printf("\n");
for (int i = rm_head; i != -1; i = linklist[i].next) {
if (linklist[i].next != -1)
printf("%05d %d %05d\n", i, linklist[i].val, linklist[i].next);
else {
printf("%05d %d %d", i, linklist[i].val, linklist[i].next);
}
}
} 整合代码提交
效率还行
#include<bits/stdc++.h>
#define MaxN 100000
using namespace std;
int head, rm_head = -1; //分别用于存储两个链表的头结点地址
int N;
struct node {
int val;
int next;
node() : val(0), next(-1) {}
} linklist[MaxN];
queue<int> St; //存储被删除结点的地址
bitset<MaxN> check(0); //用于查重
//输入和构建链表
void Input() {
scanf("%d%d", &head, &N);
int c = N;
while (c--) {
int addr, val, next;
scanf("%d%d%d", &addr, &val, &next);
linklist[addr].val = val;
linklist[addr].next = next;
}
}
//处理链表的去重问题
void handle() {
//正常删除链表结点的处理方式
int pre = head;
check[abs(linklist[head].val)] = 1;
for (int i = linklist[pre].next; i != -1; i = linklist[i].next) {
int val = abs(linklist[i].val);
if (!check[val]) {
check[val] = 1;
pre = i;
}//一旦出现重复结点,把这个结点删除就行,删除结点的操作需要双指针辅助
else {
linklist[pre].next = linklist[i].next;
St.push(i);
}
}
if (St.empty())
return;
//根据队列进行正确连接
int num = St.front();
St.pop();
rm_head = num;
while (!St.empty()) {
linklist[num].next = St.front();
num = linklist[num].next;
St.pop();
}
linklist[num].next = -1;
}
//打印链表即可---注意小坑--(地址打印五位数字,少了补0,-1时不能打印五位数)
void print() {
handle();
for (int i = head; i != -1; i = linklist[i].next) {
if (linklist[i].next != -1)
printf("%05d %d %05d\n", i, linklist[i].val, linklist[i].next);
else {
printf("%05d %d %d", i, linklist[i].val, linklist[i].next);
}
}
if (rm_head == -1)
return;
printf("\n");
for (int i = rm_head; i != -1; i = linklist[i].next) {
if (linklist[i].next != -1)
printf("%05d %d %05d\n", i, linklist[i].val, linklist[i].next);
else {
printf("%05d %d %d", i, linklist[i].val, linklist[i].next);
}
}
}
int main() {
Input();
print();
return 0;
} 



京公网安备 11010502036488号