数据结构学习笔记:顺序表的删除操作及其演化题目总结
Posted 晚风(●•σ )
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构学习笔记:顺序表的删除操作及其演化题目总结相关的知识,希望对你有一定的参考价值。
目录
前言
文章代码皆在Dev-C++ 5.11中测试,主要是总结一些方法,从而总结一些规律使自己进一步地深化学习内容,仅供参考,若有代码错误或表述不当之处,欢迎指正!
例题
例、设计一个删除算法,删除顺序表L中的第i个位置的元素,用引用变量返回。
思路:
由于这个函数删除后顺序表L有变,所以L前要有&,且我们要返回的变量也是变化的,一开始将其初始值设置为0,所以该变量前面也要加引用。
bool ListDelete(SqList &L,int i,int &e)//bool类型的函数,用于返回true和false
首先要判断删除的元素位置i是否有效,我们知道这里的i是位序(并不是数组,数组里面从0开始;而位序从1开始),所以当i小于1且i大于顺序表的长度时显示出错信息。
if (i<1||i>L.length)
return false;
由于我们要删除某个元素,并通过引用变量返回,所以这里先获得位序为i的元素(i-1),并将这个位置的元素赋值给引用变量,然后这个位置就空了即被删除。
e=L.data[i-1];
删除该元素后,我们要将后面的元素都向前移动一格,这里注意,我们先移动删除元素右边的元素,而不从最后一个元素向前移,即我们可以设置一个for循环,将位序i这个量赋给j,作为j的初始值从而开始对位序为i后的元素进行向前移一格,按之前说的,所以要将数组下标大的赋值给下标小的,即
L.data[j-1]=L.data[j];
删除后顺序表要减1,并返回true表示删除成功。
核心代码如下:
/*顺序表的删除操作 (删除L中第i个位置的元素并引用变量e返回)*/
bool ListDelete(SqList &L,int i,int &e)
if (i<1||i>L.length) //在[1,length+1]内有效
return false; //删除失败返回true
e=L.data[i-1]; //将要删除的元素赋值给e,由于是数组所以要i-1
for(int j=i; j<L.length; j++)
L.data[j-1]=L.data[j]; //将要删除的位置,第i个元素后的元素前移,先移动前面的元素,即下标大的赋值给下标小的
L.length--; //数组的长度减1
return true; //删除成功后返回true
完整代码如下:
#include<stdio.h>
#define MaxSize 10
typedef struct
int data[MaxSize];
int length;
SqList;
/*初始化顺序表*/
void InitList(SqList L)
L.length=0;
/*顺序表的输出,从头到尾输出顺序表中各元素的值*/
void DispList(SqList L)
for(int i=0; i<L.length; i++)
printf("%d ",L.data[i]);
/*顺序表的删除操作 (删除L中第i个位置的元素并引用变量e返回)*/
bool ListDelete(SqList &L,int i,int &e)
if (i<1||i>L.length) //在[1,length+1]内有效
return false; //删除失败返回true
e=L.data[i-1]; //将要删除的元素赋值给e,由于是数组所以要i-1
for(int j=i; j<L.length; j++)
L.data[j-1]=L.data[j]; //将要删除的位置,第i个元素后的元素前移,先移动前面的元素,即下标大的赋值给下标小的
L.length--; //数组的长度减1
return true; //删除成功后返回true
//主函数
int main()
SqList L;
int a;
int e=0; //初始化e的值
InitList(L);
printf("请输入建立顺序表的元素个数:\\n");
scanf("%d",&L.length);
printf("请输入整数:\\n");
for(int i=0; i<L.length; i++)
scanf("%d",&L.data[i]);
printf("当前顺序表为:\\n");
DispList(L);
printf("\\n");
printf("请输入想删除的元素位置:\\n",a);
scanf("%d",&a);
if (ListDelete(L,a,e))
printf("已删除顺序表中第%d个元素,其元素值为%d\\n",a,e);
else
printf("输入的位序i不合法,删除操作失败!\\n");
printf("当前顺序表为:\\n");
DispList(L);
return 0;
运行结果如下:
类似题目1
例、对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法实现删除线性表中所有值为x的数据元素。
思路:
通过定义一个函数来实现要求,其参数&L是因为执行删除操作后,顺序表中的元素个数会变化,另外参数x用于输入要删除的数据元素。
void del_x(SqList &L,int x)
我们通过一个for循环,还是循环遍历整个顺序表,设置两个变量i和k,其初始值都为0,目的是找到等于和不等于值为x的数据元素,k值用于记录顺序表中不等于x的数据元素次数(这个次数最后就可以作为顺序表的最终长度),i用于循环遍历顺序表,若当前的i值不等于x时,则将当前数组下标i赋给以k为数组下标的数据元素(当找到元素时,相当于将其后数据元素的数组下标i,赋给那个被找到的数据元素,即复制一个过去),且此时k++;而若等于x时,本次for循环不执行,即本次循环的k值为顺序表中不等于x的数据元素次数。
int k=0;
for(int i=0; i<L.length; i++) //遍历顺序表
if(L.data[i]!=x) //若不等于x,则将当前值赋给当前值;若不等于则不只需if内的语句,k值不变
L.data[k]=L.data[i];
k++;
所以最后我们得到的k=总长度-不等于x的数据元素个数,然后将这个值赋给L.length从而修改顺序表的长度,后面的元素都被剪除,从而达到删除所有值为x的数据元素的操作。
L.length=k; //最后将k值赋给顺序表的长度,此时长度为除掉所有为x的数据元素后的值
核心代码如下:
/*删除顺序表中所有值为x的数据元素*/
void del_x(SqList &L,int x)
int k=0; //k用于记录顺序表中不等于x的数据元素
for(int i=0; i<L.length; i++) //遍历顺序表
if(L.data[i]!=x) //若不等于x,则将当前值赋给当前值;若不等于则不只需if内的语句,k值不变
L.data[k]=L.data[i];
k++;
L.length=k; //最后将k值赋给顺序表的长度,此时长度为除掉所有为x的数据元素后的值
这里讲得有点繁杂,所以对代码进行一些修改,……,从而可观察每次循环后的当前顺序表,根据结果可可以更好理解执行情况,如下:
第零次循环(i=0),第一次循环没有找到与x=1相同的元素,所以顺序表无变化,i和k的值正常递加;第二次循环(i=3)找到目标元素,本次if条件语句下的内容不执行,k2值不变,此时数组下标为i3(由于是数组所以实际上为i4,后面的i和k都是一样)的数据元素替换数组下标为k2的数据元素;第三次循环正常运行,i和k的值正常递加,k为k3,i为i4;第四次循环又找到目标元素,所以此时数组下标为i4的数据元素替换数组下标为k3的数据元素,由于本次循环正常进行所以k值加1,为k4;第五次循环i=6不满足i<L.Length退出for循环,将k4的值赋给顺序表长度,后面的元素被剪除。
完整代码如下:
#include<stdio.h>
#define MaxSize 10
typedef struct
int data[MaxSize];
int length;
SqList;
/*初始化顺序表*/
void InitList(SqList L)
L.length=0;
/*顺序表的输出,从头到尾输出顺序表中各元素的值*/
void DispList(SqList L)
for(int i=0; i<L.length; i++)
printf("%d ",L.data[i]);
/*删除顺序表中所有值为x的数据元素*/
void del_x(SqList &L,int x)
int k=0; //k用于记录顺序表中不等于x的数据元素
for(int i=0; i<L.length; i++) //遍历顺序表
if(L.data[i]!=x) //若不等于x,则将当前值赋给当前值;若不等于则不只需if内的语句,k值不变
L.data[k]=L.data[i];
k++;
L.length=k; //最后将k值赋给顺序表的长度,此时长度为除掉所有为x的数据元素后的值
//主函数
int main()
SqList L;
int x;
InitList(L);
printf("请输入建立顺序表的元素个数:\\n");
scanf("%d",&L.length);
printf("请输入整数:\\n");
for(int i=0; i<L.length; i++)
scanf("%d",&L.data[i]);
printf("当前顺序表为:\\n");
DispList(L);
printf("\\n");
printf("请输入要删除顺序表中所有为x的元素值:\\n",x);
scanf("%d",&x);
del_x(L,x);
printf("当前顺序表为:\\n");
DispList(L);
return 0;
运行结果如下:
与例题2的相似对比总结:
类似题目2
例、删除有序顺序表中重复的数据元素,使表中所有元素的值均不同。
思路:
这道题要注意输入的顺序表是有序的,通过for循环遍历有序顺序表,分别设置参数i=0及j=1,从而查找下一个与上一个元素值不相同的元素,当不相同时,将元素向前移动,然后j++;若相同则退出本次循环,然后j++,最后得到的所有元素不重复的值统计个数,赋给L.length,此时i+1前都是不重复的元素,后面多余的元素即重复元素,即完成删除顺序表中重复的数据元素。
核心代码如下:
/*删除有序顺序表中重复的元素*/
bool Delete_same1(SqList &L)
if(L.length==0)
return false;
int i,j;
for(i=0,j=1; j<L.length; j++)
if(L.data[i]!=L.data[j]) //查找下一个与上个元素值不同的元素
L.data[++i]=L.data[j]; //找到后将元素前移动
L.length=i+1; //所有不重复的值的个数赋给L.length
return true;
对代码进行一些修改,……,从而可观察每次循环后的当前顺序表,根据结果可以更好理解执行情况,如下:
完整代码如下:
#include<stdio.h>
#define MaxSize 10
typedef struct
int data[MaxSize];
int length;
SqList;
/*初始化顺序表*/
void InitList(SqList L)
L.length=0;
/*顺序表的输出,从头到尾输出顺序表中各元素的值*/
void DispList(SqList L)
for(int i=0; i<L.length; i++)
printf("%d ",L.data[i]);
/*删除有序顺序表中重复的元素*/
bool Delete_same1(SqList &L)
if(L.length==0)
return false;
int i,j;
for(i=0,j=1; j<L.length; j++)
if(L.data[i]!=L.data[j]) //查找下一个与上个元素值不同的元素
L.data[++i]=L.data[j]; //找到后将元素前移动
L.length=i+1; //所有不重复的值的个数赋给L.length
return true;
//主函数
int main()
SqList L;
InitList(L);
printf("请输入建立顺序表的元素个数:\\n");
scanf("%d",&L.length);
printf("请输入整数:\\n");
for(int i=0; i<L.length; i++)
scanf("%d",&L.data[i]);
printf("当前顺序表为:\\n");
Delete_same1(L);
DispList(L);
return 0;
运行结果如下:
与例题的类似对比:
类似题目3
例、删除顺序表中重复的数据元素,使表中所有元素的值均不同。
【本题代码参考文章:https://blog.csdn.net/qq_42285148/article/details/117393638】
思路:
这题与题目2相比也就是将有序顺序表改为顺序表,设置两个for循环,从内自外循环遍历顺序表,内层循环从顺序表的第二位元素开始,跟上一题类似,不过这里是要查找下一个与上个元素值相同的元素,这里再进行分支若当前查找的下一个元素至顺序表的末尾,则将下一个元素赋值为0,且顺序表的长度减一;若不是顺序表的末尾,则继续进行一个for循环,对其中将下标大的元素赋给下标小的元素,将元素全部左移,然后再将顺序表的长度减一,最后再j–,继续回到两层for循环,检查下一个与上个元素值相同的元素。
核心代码如下:
/*删除顺序表中重复的元素*/
bool Delete_same2(SqList &L)
if(L.length==0)
return false;
int i,j,k;
for(i=0;i<L.length;i++) //从顺序表的第一位数据元素遍历整个顺序表
for(j=i+1;j<L.length;j++) //从顺序表的第二位数据元素遍历整个顺序表
if(L.data[j]==L.data[i]) //查找下一个与上个元素值相同的元素
if(j==L.length) //若下一个查找的元素到顺序表的表尾
L.data[j]=0;
L.length--;
else
for(k=j;k<L.length;k++) //若下一个查找的元素还没到表尾
L.data[k]=L.data[k+1]; //将下标大的元素赋给下标小的元素
L.length--; //顺序表的长度减1
j--;
return true;
完整代码如下:
#include<stdio.h>
#define MaxSize 10
typedef struct
int data[MaxSize];
int length;
SqList;
/*初始化顺序表*/
void InitList(SqList L)
L.length=0;
/*顺序表的输出,从头到尾输出顺序表中各元素的值*/
void DispList(SqList L)
for(int i=0; i<L.length; i++)
printf("%d ",L.data[i]);
/*删除顺序表中重复的元素*/
bool Delete_same2(SqList &L)
if(L.length==0)
return false;
int i,j,k;
for(i=0;i<L.length;i++) //从顺序表的第一位数据元素遍历整个顺序表
for(j=i+1;j<L.length;j++) //从顺序表的第二位数据元素遍历整个顺序表
if(L.data[j]==L.data[i]) //查找下一个与上个元素值相同的元素
if(j==L.length) //若下一个查找的元素到顺序表的表尾
L.data[j]=0;
L.length--;
else
for(k=j;k<L.length;k++) //若下一个查找的元素还没到表尾
L.data[k]=L.data[k+1]; //将下标大的元素赋给下标小的元素
L.length--; //顺序表的长度减1
j--;
return true;
//主函数
int main()
SqList L;
InitList(L);
printf("请输入建立顺序表的元素个数:\\n");
scanf("%d",&L.length);
printf("请输入整数:\\n");
for(int i=0; i<L.length; i++)
scanf("%d",&L.data[i]);
printf("当前顺序表为:\\n");
DispList(L以上是关于数据结构学习笔记:顺序表的删除操作及其演化题目总结的主要内容,如果未能解决你的问题,请参考以下文章
数据结构学习笔记——顺序表的基本操作(超详细最终版+++)建议反复看看ヾ(≧▽≦*)o