在有序链表中,如果有重复值,则重复值是聚集在一块的,你只需要判断此节点的的下一个节点的值是否与此节点相同,相同则把下一个节点删除,不同则指针后移,直到遍历完整个链表。`
这里写代码片
void Pur1_linklist(Link H)
{
Link p,pre;
pre=H->next;
p=pre->next;
if(!pre)
printf("ERROR!");
else
{
while(p)
{
if(p->data==pre->data)//判断下一个节点值是否与此节点值相同,相同则删除,不同则指针后移
{
pre->next=p->next;
free(p);
p=pre->next;
}
else
{
pre=p;
p=p->next;
}
}
}
}
对于无序链表来说,因为数据都是无序的,所以重复的值不一定会聚集在一块,例如:9 6 5 3 14 9 3 6 7 5 3
第一种处理思想就是定义两个指针,架两层循环,pre先定位在第一个节点上,然后用p指向它的下一个节点,然后p开始逐渐后移,判断p节点的值是否与pre的值相同。这种方法思想很简单,但是时间复杂度为O(n^2),显然感觉还是可以优化的,这样就有了第二种方法
第二种方法的思想是浪费空间换时间,可以先定义一个足够大的数组,先给数组赋0,然后开始遍历链表,
然后判断语句,if( a[ p - >next - >data] == 0) a[ p - >next - >data] ++;如果节点值在数组对应下标中的元素的值为0,则此节点值所对应的数组元素++,继续遍历链表,如果节点值在数组对应下标中的元素的值不为0,则说明在此节点之前,已经有过相同的值,就将此节点删除。
这里写代码片
void Pur2_linklist(Link Head)
{
Link p,q;
int a[N]={'0'};
p=Head;
while(p->next)
{
if(a[p->next->data]==0)
{
a[p->next->data]++;
p=p->next;
}
else
{
q=p->next;
p->next=q->next;
free(q);
}
}
}
这种方法的时间复杂度为O(n),但是如果你的链表中有的节点的值很大时,那么你的数组也要定义的非常大,会造成大量空间的浪费,暂时还没想到改善的方法,如果有人有更好的方法的话,欢迎交流。