7-4 链表去重 (10 分)
给定一个带整数键值的链表 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
这题数据结构花了两三个钟来写,终于写出来了但是!!运行超时了!!!
10分就拿了7分
但是感觉写着挺好玩的?(bushi)所以拿出来作为俺的第一篇博客辽
以下是代码
#include<iostream>
#include<stdlib.h>
#define MAXSIZE 100
using namespace std;
typedef struct LNode
{
string this_loc;
int num;
string next_loc;
LNode* next;
}LNode, * LinkList;
void print_list(LinkList L) //输出链表函数
{
LNode* p = L->next;
while (p)
{
cout << p->this_loc << " " << p->num << " " << p->next_loc << endl;
p = p->next;
}
}
void function1(LinkList& new_list, LinkList& del_list) //对排好序链表的去重函数
{
int a[MAXSIZE];
int i = 0;
//新链表扫描指针p
LNode* p = new_list->next;
LNode* pre = p;
//被删除元素的链表扫描指针d_l
LNode* d_l = del_list;
LinkList r;
//将新链表出现过的元素存进数组
a[i] = abs(p->num);
i++;
p = p->next;
while (p)
{
for (int j = 0; j < i; j++)
{
if (p!=NULL && abs(p->num) == a[j]) //有重复值
{
//添加至被删除元素的链表
r = new LNode;
r->next = NULL;
r->this_loc = p->this_loc;
r->num = p->num;
r->next_loc = p->next_loc;
d_l->next = r;
d_l = r;
//新链表删除该元素
pre->next = p->next;
p = p->next;
break;
}
else if (p!=NULL && j == i - 1) //没有重复元素
{
a[i] = abs(p->num); //添加至数组
i++;
pre = p;
p = p->next;
break;
}
else
{
continue;
}
}
}
}
void function2(LinkList& new_list, LinkList& del_list) //修正新链表与被删除链表的this_loc和next_loc的函数
{
LNode* pre_n = new_list->next;
LNode* n = pre_n->next;
LNode* pre_d = del_list->next;
LNode* d = pre_d->next;
while (n)
{
if (n->next != NULL)
{
pre_n->next_loc = n->this_loc; //将n指向的元素的this_loc赋值给上一元素的next_loc
pre_n = n;
n = n->next;
}
else
{
pre_n->next_loc = n->this_loc;
n->next_loc = "-1";
n = n->next;
}
}
while (d)
{
if (d->next != NULL)
{
pre_d->next_loc = d->this_loc; //将d指向的元素的this_loc赋值给上一元素的next_loc
pre_d = d;
d = d->next;
}
else
{
pre_d->next_loc = d->this_loc;
d->next_loc = "-1";
d = d->next;
}
}
}
int main()
{
string first;
int n;
cin >> first; //输入首地址
cin >> n;
//创建并输入链表
LinkList s;
s = new LNode;
s->next = NULL; //创建头节点
LNode* r = s;
LNode* p;
for (int i = 0; i < n; i++)
{
p = new LNode;
p->next = NULL;
r->next = p;
r = p;
cin >> p->this_loc >> p->num >> p->next_loc;
}
//创建新链表new_list使原链表按逻辑顺序排序
LinkList new_list;
new_list = new LNode;
new_list->next = NULL;
LNode* n_l = new_list;
//定义原链表的扫描指针loc进行判断
LNode* loc = s->next;
while (loc)
{
if (loc->this_loc == first)
{
LinkList p;
p = new LNode;
p->next = NULL; //创建节点
p->this_loc = loc->this_loc;
p->num = loc->num;
p->next_loc = loc->next_loc; //赋值
n_l->next = p; //连接新链表
n_l = p;
first = loc->next_loc; //改变判断条件
loc = s->next; //从头扫描
continue;
}
else loc = loc->next;
}
//创建由被删除元素组成的链表
LinkList del_list;
del_list = new LNode;
del_list->next = NULL;
function1(new_list, del_list); //function1进行新链表去重, 并将被删除元素放入del_list
function2(new_list, del_list); //function2进行链表内容的修正
//输出两个链表
print_list(new_list);
print_list(del_list);
}