删除有序链表的重复元素

若链表的元素无序的话先有序插入新建链表,再删除重复元素

#include <stdio.h>
#include<stdlib.h>

typedef struct student {
    int num;
    struct student* pnext;
}stu, * pstu;

void list_print(pstu phead)
{
    while (phead)
    {
        printf("%d ", phead->num);
        phead = phead->pnext;
    }
}

 void list_sort_insert(pstu* pphead, stu** pptail, int i) {     //有序插入
     pstu pnew = (pstu)calloc(1, sizeof(stu));
     pnew->num = i;
     pstu pcur, ppre;
     pcur = ppre = *pphead;
     if (*pphead == NULL) { *pphead = pnew; *pptail = pnew; }                            //链表为空,头尾指针指向新节点
     else if (i < (*pphead)->num) { pnew->pnext = *pphead; *pphead = pnew; }             //判断是否插入头部,头插法
     else {                                                                              //否则插入
         while (pcur) {
             if (i > (pcur->num)) { ppre = pcur; pcur = pcur->pnext; }               //插入值大于pcur->num,ppre指向pcur,pcur指向下一个节点
             else { ppre->pnext = pnew; pnew->pnext = pcur; break; }                  //ppre节点的pnext指向新节点,新节点的pnext指向pcur
         }
         if (pcur == NULL) { (*pptail)->pnext = pnew; *pptail = pnew; }               //插入到尾部,尾插法
     }
 }

 pstu del_same_ele(pstu head)  //删除重复元素
 {
     if (head == NULL) { return NULL; }  //空链表
     pstu pcur, ppre;
     ppre = head;
     pcur = head->pnext;
     if (head->pnext == NULL) { return head; } //只有一个头节点
     while (pcur) {
         while (pcur->num == ppre->num)          //前后节点的值相同
         {
            ppre->pnext = pcur->pnext;           //ppre后一个节点设为pcur的后一个节点
            free(pcur);                         //删除pcur节点
            pcur = ppre->pnext;                 //删除节点的后一个节点赋为pcur
            if (pcur == NULL) break;            //若ppre是最后一个节点 
         }
         if (pcur != NULL) {                //前后节点的值不同且后一节点不为空
             ppre = pcur;            //ppre和pcur都往后移一位
             pcur = pcur->pnext;
         }
         else break;
     }
     return head;
 }
int main() {
    pstu phead1, ptail1;
    phead1 = ptail1 = NULL;
    int i;
    printf("list:");
    while (scanf_s("%d", &i) != EOF)
    {
        list_sort_insert(&phead1, &ptail1, i);
    }
    list_print(del_same_ele(phead1));
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值