删除单链表中绝对值相同的节点-2015年408真题![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2621ffeb1ce0a0a012f68cfd386b73e8.png)
1.算法设计思想
算法的核心思想是用空间换时间。使用辅助数组记录链表中己出现的数值,从而只需对链表进行一趟扫描。
因为|data|≤n,故辅助数组a的大小为n+ 1,各元素的初值均为0。依次扫描链表中的各结点,同时检查a[|data]的值,如果为0,则保留该结点,并令a[|data|] = 1;否则,将该结点从链表中删除。
2.代码描述
//
// main.cpp
// 2015
//
// Created by MacBook Pro on 2022/11/23.
//
#include <iostream>
#include<math.h>
using namespace std;
struct Lnode{
int data;
Lnode *link;
};
typedef Lnode* Linklist;
Linklist get_data(int m)//建表 尾插法,也可以建立尾指针
{
Linklist head=new Lnode;
Linklist t=head;
for(;m>0;m--)
{
Lnode *p=new Lnode;
cin>>p->data;
head->link=p;
head=head->link;
}
head->link=NULL;
return t;
}
void delete_repeat(Linklist p,int n)
{
int *a=new int[n+1];//记录绝对值为i的数是否已经出现
int i;
for(i=0;i<=n;i++)//初值置为0,表示未出现
a[i]=0;
while(p->link)
{
int t=abs(p->link->data);
if(a[t]==0)
{
a[t]=1;//首次出现,记录为已出现
p=p->link;//保留结点
}
else{//重复出现,删除
Lnode *t=p->link;
p->link=p->link->link;
delete t;
}
}
delete []a;
}
void print_Linklist(Linklist head)
{
while(head->link)
{
head=head->link;
cout<<head->data<<' ';
}
cout<<endl;
}
int main()
{
int m,n;
cin>>m>>n;
Linklist head=get_data(m);
delete_repeat(head, n);
print_Linklist(head);
return 0;
}
3.复杂度分析
时间复杂度为O(m),空间复杂度为O(n)