【数据结构与算法】线性表——删除重复元素

线性表是一种随机存取的结构,和链表不同,链表顺序存取的结构。但是,线性表是一种顺序存储的结构,而链表是链式存储结构。两者都是线性的,但区别不同。

进入主题:

1.假如有一串数据元素,要求删除其中的重复元素。

首先想到的是用两层循环,第一层从第一个元素开始,第二层从第一层元素的下一个元素开始。

就是假如第一层是ai元素,则第二层就为ai+1元素。

函数实现:

 1 void Purge1(ElemType A[],int &n){//ElemType表示任意数据类型,以后不再说明//n为线性表的长度
 2     int i=0,j;
 3     while(i<n){
 4     j=i+1;
 5     while(j<n){
 6       if(A[j]==A[i])
 7         Deletelist(A,n,j+1);//具体函数实现最后给出
 8       else
 9         j++;
10     }
11     i++;
12   }
13 }

2.如果这些元素是按递增排列,且数据量很大的话,使用上面的算法就会造成时间上的浪费。

那要怎么优化呢?

具体想法就是用一个变量k记录重复的个数,然后第i个元素和第i+1个元素进行比较,若相等,则k自增。否则第i+1个元素的值赋值给第i-k+1个元素的值。当k=0时,其实就是自己赋值给自己。

举个例子:

1  2  2  3  4  6  6  6  8  9

i从第1个元素开始,到第2个元素时,此时第2个元素和第3个元素相等,执行k++。然后进行下一次循环,第3个元素不等于第4个元素,因为此时k=1,故第3个元素被赋予第4个元素的值3。然后直到第6个元素,此时又相等,k=2。第7个也相等,k=3。然后到第8个元素,第6个元素被赋予值8,就是第9个元素的值。然后最后一个元素9。此时表的长度为n=10-k=7。

函数实现:

1 void Purge2(int *A, int &n) {
2   int i = 0, k = 0;//k是重复的次数或是要删除的数的个数
3   for (i = 0; i < n - 1; i++)
4     if (A[i] != A[i + 1])
5       A[i-k+1] = A[i + 1];
6     else
7       k++;
8   n = n - k;
9 }

经过小规模的测试没有发现问题。

经过两函数的分析,可以看出第一个函数使用的是两层循环,而第二个函数只使用了一层循环达到了效果。

避免了不必要的时间浪费。

附上Deletelist函数:

1 void Deletelist(int *A, int &n, int i) {
2   int j;
3   if (i<1 || i>n)//这条可以无视
4     cout << "超出范围!";
5   for (j = i; j < n; j++)
6     A[j - 1] = A[j];
7   n--;
8 }

碎碎念:本人是个大二学生,兴趣就是写代码,通过写代码来解决算法题,以此来获得成就感。目前感兴趣的方向是网络安全。我也喜欢在闲余时间玩玩游戏,看看资料。

posted @ 2018-09-24 21:02  1000sakura  阅读(4721)  评论(2编辑  收藏  举报