C语言删除线性表相同元素但保留一个(含测试源码)

本博文源于博主的一次数据结构的练习,标题为:删除线性表中值相同的元素(值相同的元素仅保留第一个)。博文里含有对其完整源码实现,并对其进行人脑试运行代码,堪比是新手菜鸟级别教程.

0. 题目再现

设计一个算法,删除顺序表中值相同的元素(值相同的元素仅仅保留第一个),使得顺序表中所有元素的值均不相同。

1.测试效果

在这里插入图片描述

2.解题思路

假设L.data[0]是不重复的值,然后每次进行比较,在对线性表元素进行逐个检测,如果与不重复元素区的元素的值重复,则不作任何处理,否则将其插入不重复元素区.

3.核心源码&参考文献

bool deleteSame(SeqList& L) {
    
    
    if(L.n == 0){
    
    
        printf("table is empty\n");
        return false;
    }
    int i,j,k = 0;
    for( i = 1;i<L.n;i++) {
    
    
        for(j =0;j<=k;j++)
            if(L.data[i] == L.data[j])
                break;
            if(j > k && ++k != i)
                L.data[k] = L.data[i];

    }
    L.n = k + 1;
    return true;

}

殷人昆著.数据结构与算法解析.北京:清华大学出版社,2021.4

4. 时空分析

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( n ) O(n) O(n)

5.完整源码

#include<stdio.h>
#include<stdlib.h>
#define initSize 100
typedef int DataType;
typedef struct{
    
    
    DataType *data;
    int maxSize,n;
}SeqList;


void initList(SeqList& L) {
    
    
    //调用方式initList(L),输入:未初始化的顺序表L;输出;已初始化的顺序表L
    L.data = (DataType *) malloc(initSize*sizeof(DataType));
    if(!L.data) {
    
    
        printf("分配有误....\n");
        exit(1);
    }
    L.maxSize = initSize;
    L.n = 0;
}



void createList(SeqList &L,DataType A[],int n) {
    
    
    initList(L);
    for (int i = 0; i < n; i++)
        L.data[i] = A[i];
    L.n = n;
}
void printList(SeqList& L) {
    
    
    for(int i =0;i<L.n;i++)
        printf("%d ",L.data[i]);
    printf("\n");

}


bool deleteSame(SeqList& L) {
    
    
    if(L.n == 0){
    
    
        printf("table is empty\n");
        return false;
    }
    int i,j,k = 0;
    for( i = 1;i<L.n;i++) {
    
    
        for(j =0;j<=k;j++)
            if(L.data[i] == L.data[j])
                break;
            if(j > k && ++k != i)
                L.data[k] = L.data[i];

    }
    L.n = k + 1;
    return true;

}



int main()
{
    
    

    SeqList L;
    int arr[5]={
    
    1,2,5,2,2};
    createList(L,arr,sizeof(arr)/sizeof(int));
    printList(L);
    printf("\ndeleted....\n");
    deleteSame(L);
    printList(L);
    return 0;
}


6.人脑试跑

假如我们输入的是[1,2,5,2,2],我们删去并留下一个2,因此最后答案应该就是[1,2,5],运行程序,我们人脑如下

6.1 i= 1

j = 0 j<= 0
L.data[1]=2 != L.data[0]=1
j ++ =1 比 k 大了,j的for循环执行完毕
j=1 > 0 && 1 == 1不满足 不执行if语句

6.2 i= 2

j = 0 ,j<= 1
L.data[2] =5 == L.data[0]=1 不满足
L.data[2]=5 == L.data[1] = 2 不满足
j = 2 > 1 && 2 != 2 不满足if语句,不执行

6.3 i=3

j= 0 ,j<=2
L.data[3] = 2 == L.data[0] = 1 不满足
L.data[3] = 2 == L.data[1] = 2 满足 直接break
if(1 > 2 )不满足if语句,不执行 , ++k也没有执行

6.4 i=4

j = 0 j<= 2
L.data[4] = 2 == L.data[1] = 1 不满足
L.data[4] = 2 == L.data[1] = 2 满足,直接break
if(1 > 2 )不满足if语句,不执行 , ++k也没有执行

故最终L.n = k+1=2+1=3,符合也就是[1,2,5]

7.总结

题目里最耀眼的是

for( i = 1;i<L.n;i++) {
    
    
    for(j =0;j<=k;j++)
        if(L.data[i] == L.data[j])
            break;
        if(j > k && ++k != i)
            L.data[k] = L.data[i];

}

Guess you like

Origin blog.csdn.net/m0_37149062/article/details/120744745