删除无序链表中的重复值

在有序链表中,如果有重复值,则重复值是聚集在一块的,你只需要判断此节点的的下一个节点的值是否与此节点相同,相同则把下一个节点删除,不同则指针后移,直到遍历完整个链表。`

这里写代码片
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),但是如果你的链表中有的节点的值很大时,那么你的数组也要定义的非常大,会造成大量空间的浪费,暂时还没想到改善的方法,如果有人有更好的方法的话,欢迎交流。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值