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