删除单链表中的重复元素(处理相邻情况)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef struct LNode
{
    int data;
    struct  LNode* next;
} LNode, * LinkList;//typedef是可以同时为两个变量取名字的,在这里就是把struct LNode改为了LNode,把struct LNode*改成了LinkList,这为后面的操作带来了很大的方便!
void List_Insert(LinkList &L)
{
    LNode* s=NULL;
    L = (LNode*)malloc(sizeof(LNode));//这里是创建一个头结点
    int x = 0;
    if (L != NULL)
    {
        L->next = NULL;
        LNode* r = L;
        cin >> x;
        while (x != 9999)
        {
            s = (LNode*)malloc(sizeof(LNode));
            if (s != NULL)
            {
                s->data = x;
                r->next = s;
                r = s;
                cin >> x;
            }
        }
        r->next = NULL;
    }
//这里所做的函数就是当你需要使用链表的时候,你每输入一个元素,系统就会给你开辟一块空间,并把你的元素存储进去,而不要直接开辟一个多大空间的链表,只体现了对内存空间的合理运用!
}
void PrintLinkList(LinkList L)
{
    printf("打印链表\n");
    LNode* r = L->next;
    while (r != NULL)
    {
        if (r->next != NULL)
            cout << r->data << "-->";
        else
            cout << r->data;//这里是为了打印的时候更加的美观所作的一个调整!(小细节)
        r = r->next;
    }
    printf("\n");
}
void DeleteLinkList(LinkList& L)
{
    LNode* r = L->next, * q;
    if (r != NULL)
    {
        while (r->next!=NULL)
        {
            LNode* s = r;//如果在r的后面加上一个next的话,那么就会保留第一个元素不去和其它的元素进行比较!所以
            //这样就不能够处理一种情况——当第一个元素与第二个元素相同的时候!
            while (s->next!=NULL)//我不知道这里为什么会说明未初始化的内存*q,就算我在前面加上一个制空指针,还是没用!
            {
                q = s->next;
                if (s->data == q->data)
                {
                    s->next = q->next;//删除相邻的就这么一个操作就可以完成,就是交换头结点罢了!
                    free(q);//这里释放所开辟的空间就不用多说
                    q = NULL;//注意:释放完之后,还是要命名为空指针,这样更加地安全!
                }
                else
                {
                    s = s->next;
                }
            }
            r = r->next;
        }
    }
 //   return (L);
}
int main()
{
    LinkList L;//L是头指针,创建链表,这里使用LinkList是为了更好知道L是链表。
    void List_Insert(LinkList & L);//这里的&不是取地址,而是引用,也就是L的别名!
    void PrintLinkList(LinkList L);//这里只是打印链表,所以是不用改变链表的内容的,所以就不使用引用了!
    void DeleteLinkList(LinkList & L);
    List_Insert(L);
    PrintLinkList(L);//既然建立了引用,那么这时候就可以把它本身传进去了,这比指针方便多了!
    DeleteLinkList(L);//这段代码千万别屏蔽,刚才总是出错
    PrintLinkList(L);
    return 0;
}
//以上代码可以实现删除的功能,但是有一种情况不可以实现,就是当首两个元素是相同的时候,无法删除!
//上面的问题出现在第185行,就是因为比较元素的时候,并没有把第一个元素加入在比较的行列,所以就算有相同的元素,也会自动地跳过第一个元素!
//总结:当然这个删除还不够严谨,因为这种只能够删除相邻的元素,当相同的元素互不相邻的时候,这一种方式就不行了!

当然这并不是最好的删除重复元素的代码,因为没能处理不相邻的情况,希望有大佬能来指点指点,并给我一些建议!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值