删除重复元素(顺序表、单链表)

简介: 用顺序表和单链表分别实现删除操作

一、顺序表删除重复元素

1.1 问题描述

【问题描述】
设一顺序表有若干元素,编写程序实现删除表中值重复的元素,即重复元素只保留一个。
【输入形式】
第一行输入一个N(N不大于100),表示顺序表的长度;
第二行输入N个整数,表示顺序表元素;
【输出形式】
输出去重后的顺序表。
【样例输入】
7
2 2 2 3 3 2 2
【样例输出】
2 3

1.2 具体算法

顺序表实现删除重复元素,只需要找到重复元素的位置,再执行删除操作就好了
注意每次删除完以后要让第二重循环重新判断,否则会跳值,假设你删除的是第5个元素,删除完了以后,你的顺序表第5个元素后面的每个元素都向前移了1位,此时第5个元素实际上是本来的第6个元素,由于删除后j++了,那么下一次循环判断将从第6个元素开始判断,这样我们会漏掉对第5个元素的判断,所以我们应该每删除一个重复元素后让j--,这样我们删除掉第5个元素后再寻找的时候其实还是从第5个元素(删除前的第6个元素)开始判断。
简单来说,如果没有j--,那么当我们遇到连续重复元素的时候将只会删除1个重复元素,并不会将重复的元素都删除掉。

void Delete_Same_List(PList L){
    int i,j,k;            
    for(i=0;i<L->len;i++){        //第一重循环
        for(j=i+1;j<L->len;j++){        //第二重循环,用于寻找重复的元素
            if(L->data[i]==L->data[j]){
                for(k=j;k<L->len-1;k++){    //第三重循环,用于删除重复的元素
                    L->data[k]=L->data[k+1];
                }
                L->len--;         //每删除一个,顺序表长度减少1
                j--;              //每删除一个,第二重循环要重新判断
            }              //切记要重新判断,不然j其实是j++,会跳过一个值不判断
        }
    }
}

1.3 代码实现

1.3.1 完整代码

#include<stdio.h>
#include<malloc.h>
#define SIZE 10
#define INCREAM 10
typedef struct List{
    int * data;
    int len;
    int size;
}List,*PList;
PList Init_List(PList L){
    L->data=(int *)malloc(sizeof(int)*SIZE);
    L->len=0;
    L->size=SIZE;
    return L;
}
void Creat_List(PList L){
    int n,i;
    scanf("%d",&n);
    if(L->len==L->size){
        L->data=(int *)realloc(L->data,(L->size+INCREAM)*sizeof(int));
        L->size+=INCREAM;
    }
    for(i=0;i<n;i++){
        scanf("%d",&L->data[i]);
        L->len++;
    }
}
void Delete_Same_List(PList L){
    int i,j,k;
    for(i=0;i<L->len;i++){
        for(j=i+1;j<L->len;j++){
            if(L->data[i]==L->data[j]){
                for(k=j;k<L->len-1;k++){
                    L->data[k]=L->data[k+1];
                }
                L->len--;
                j--;
            }
        }
    }
}
void Print_List(PList L){
    int i;
    for(i=0;i<L->len;i++){
        printf("%d ",L->data[i]);
    }
    printf("\n");
}
int main(){
    List L;
    Init_List(&L);
    Creat_List(&L);
    Delete_Same_List(&L);
    Print_List(&L);
    return 0;
}

1.3.2 运行结果

1.png

二、删除带头结点的单链表中值重复的元素

2.1 问题描述

【问题描述】
建立带头结点的单链表,编写程序实现删除表中值重复的元素,即重复元素只保留一个。
【输入形式】
第一行输入一个N,表示建表的长度;
第二行输入N个整数,表示数据元素。
【输出形式】
输出去重后的单链表元素。
【样例输入】
5
2 2 2 3 3
【样例输出】
2 3

2.2 具体算法

删除带头结点单链表中值重复的元素时,我们要定义一个r用来保存要删除结点的前面一个结点。这样方便删除操作。

void Delete_Same_Node(PNode head){
    PNode p,q,r;
    p=head->next;
    while(p){
        r=p;        //r保存p,r是q前面的结点
        q=p->next;    //q是p的下一个结点
        while(q){    //循环遍历
            if(p->data==q->data){    //当找到了重复元素时,执行删除操作  
                PNode s=q;
                r->next=s->next;    //r是q前面的结点
                q=q->next;          //删除后要让q变成q后面的结点,继续循环判断
                free(s);
            }else{
                r=r->next;          //r始终是q前面的结点,便于执行删除操作
                q=q->next;
            }
        }
        p=p->next;
    }
}

2.3 代码实现

2.3.1 完整代码

#include<stdio.h>
#include<malloc.h>
typedef struct Node{
    int data;
    struct Node * next;
}Node,*PNode;
PNode Init_Node(){
    PNode head=(PNode)malloc(sizeof(Node));
    head->next=NULL;
    return head;
}
void Creat_Node(PNode head){
    int i,n;
    scanf("%d",&n);
    PNode Last=head;
    for(i=0;i<n;i++){
        PNode Pnew=(PNode)malloc(sizeof(Node));
        scanf("%d",&Pnew->data);
        Pnew->next=NULL;
        Last->next=Pnew;
        Last=Pnew;
    }
}
void Delete_Same_Node(PNode head){
    PNode p,q,r;
    p=head->next;
    while(p){
        r=p;
        q=p->next;
        while(q){
            if(p->data==q->data){
                PNode s=q;
                r->next=s->next;
                q=q->next;
                free(s);
            }else{
                r=r->next;
                q=q->next;
            }
        }
        p=p->next;
    }
}
void Print_Node(PNode head){
    PNode p=head->next;
    while(p){
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}
int main(){
    PNode p;
    p=Init_Node();
    Creat_Node(p);
    Delete_Same_Node(p);
    Print_Node(p);
    return 0;
}

2.3.2 运行结果

2.png

目录
相关文章
|
1天前
|
存储 缓存
【顺序表和链表的对比】
【顺序表和链表的对比】
数据结构实验之链表七:单链表中重复元素的删除
数据结构实验之链表七:单链表中重复元素的删除
|
10月前
|
存储
顺序表和链表(三)
顺序表和链表
36 0
|
1天前
|
算法 程序员
【算法训练-链表 四】【链表删除】:删除链表的倒数第N个节点、删除有序链表中的重复元素、删除有序链表中的重复元素II
【算法训练-链表 四】【链表删除】:删除链表的倒数第N个节点、删除有序链表中的重复元素、删除有序链表中的重复元素II
43 0
|
6月前
|
索引
LeetCode题:83删除排序链表中的重复元素 141环形链表
LeetCode题:83删除排序链表中的重复元素 141环形链表
28 0
LeetCode题:83删除排序链表中的重复元素 141环形链表
|
10月前
|
存储
顺序表和链表(一)
顺序表和链表
46 0
|
10月前
|
存储
顺序表和链表(二)
顺序表和链表
31 0
|
11月前
|
存储
顺序表和链表的比较
这段时间开始学习软考里面的内容,对顺序表和链表,比较着学习理解的更多了,跟大家分享一下。