- 1.完整删除操作代码
- 2.单讨论其中的删除操作
- 3.引出删除操作中出现的疑问
- 4.验证上述疑问
- 5.结论
#include2.单讨论其中的删除操作#include //#include #define N 10 //1.定义结构体Book(结点) typedef struct { char id[N]; //书号 char name[N]; //书名 float price; //书价 }Book; //2.定义顺序表 typedef struct{ //数组(存放数据元素,即每本书) Book *elem; //数组长度(可存放多少数据元素) int length; }SqList; //3.初始化顺序表 void InitSqList(SqList *L){ //为顺序表中每个数据元素开辟空间 L->elem=(Book*)malloc(sizeof(Book)*N); //初始数组长度为0 L->length=0; } //4.创建顺序表(创建n个数据元素) void CreateSqList(SqList *L,int n){ int i=0; //循环输入n个数据元素 for(;i elem[i].id,&L->elem[i].name,&L->elem[i].price); //表长增加 L->length++; } } //5.输出顺序表 void PrintSqList(SqList *L){ int i=0; for(;i length;i++){ printf("第%d本书的书号,书名,书价:",i+1); //输出每本书的书号,书名,书价 printf("%s %s %.2fn",L->elem[i].id,L->elem[i].name,L->elem[i].price); } } //删除某个位置的元素 //删除数组中第i-1上的数据元素,删除指定位置的元素后,将此位置之后的所有数据元素向前移动一位,最后线性表长度减1 int DeleteList(SqList *L,int i){ //位置i(对应下标i-1)的元素 //判断顺序表非空 if(L->length==0) return -1; //判断下标符合要求 if(i<1 || i>L->length) return -1; //删除目的位置元素 //*b=L->elem[i-1]; //向前移动元素 if(i<=L->length){ //注意这里的等号,否则无法删除表尾数据元素 int j; //如果是表尾数据元素j=L->length,则不执行 for循环,直接进行 L->length--; for(j=i;j length;j++){ L->elem[j-1]=L->elem[j]; } //表长减1 L->length--; } } //主函数 int main(){ int n,i; //输入n个数据元素,插入位置i (对应下标i-1) Book b; //定义一本书b SqList L; //定义表L InitSqList(&L); //初始化 InitSqList(SqList *L) //为顺序表添加的数据元素个数 printf("为顺序表添加的数据元素个数:"); scanf("%d",&n); //创建含有n个数据元素的顺序表 CreateSqList(SqList *L,int n) CreateSqList(&L,n); //输出顺序表 PrintSqList(SqList *L) PrintSqList(&L); printf("从顺序表中删除元素,要删除的元素位置为:"); scanf("%d",&i); //删除目标位置元素 DeleteList(&L,i); //输出顺序表 PrintSqList(SqList *L) PrintSqList(&L); return 0; }
//删除某个位置的元素
//删除数组中第i-1上的数据元素,删除指定位置的元素后,将此位置之后的所有数据元素向前移动一位,最后线性表长度减1
int DeleteList(SqList *L,int i){ //位置i(对应下标i-1)的元素
//判断顺序表非空
if(L->length==0)
return -1;
//判断下标符合要求
if(i<1 || i>L->length)
return -1;
//向前移动元素
if(i<=L->length){ //注意这里有等号,否则无法删除表尾数据元素
int j;
//如果是表尾数据元素,则不执行 for循环,直接进行 L->length--;
for(j=i;jlength;j++){
L->elem[j-1]=L->elem[j];
}
//表长减1
L->length--; //自动释放末尾空间
}
}
上述删除的原理是:要删除的元素的后一个元素向前移动,覆盖掉这个要删除的元素,以达到删除此元素的目的。
3.引出删除操作中出现的疑问表中元素向前移动时,后一个元素的副本覆盖前一个元素。而这后一个元素本身还存在于存储空间中。
例如:
#includeint main(){ int a[2]={1,2}; printf("移动前数组第一个位置元素:%d,第二个位置元素:%dn",a[0],a[1]); a[0]=a[1]; printf("移动后数组第一个位置的元素:%d,第二个位置的元素:%dn",a[0],a[1]); }
疑问:表长减1,是否只是表的长度减了1,而实际上这个末尾元素还停留在存储空间中???亦或表长减1会将末尾元素从存储空间中释放???
4.验证上述疑问通过在删除操作的函数中添加2句打印数据元素来验证上述疑问
//删除某个位置的元素
//删除数组中第i-1上的数据元素,删除指定位置的元素后,将此位置之后的所有数据元素向前移动一位,最后线性表长度减1
int DeleteList(SqList *L,int i){ //位置i(对应下标i-1)的元素
//判断顺序表非空
if(L->length==0)
return -1;
//判断下标符合要求
if(i<1 || i>L->length)
return -1;
//删除目的位置元素
//*b=L->elem[i-1];
//向前移动元素
if(i<=L->length){ //注意这里的等号,否则无法删除表尾数据元素
//为验证新添的语句,未经过移动和表长减1操作时,打印末尾元素的值
printf("%s %s %.2fn",L->elem[i-1].id,L->elem[i-1].name,L->elem[i-1].price);
int j;
//如果是表尾数据元素,则不执行 for循环,直接进行 L->length--;
for(j=i;jlength;j++){
L->elem[j-1]=L->elem[j];
}
//表长减1
L->length--;
//为验证新添的语句,经过表长减1后查询末尾元素是否存在
printf("%s %s %.2fn",L->elem[i].id,L->elem[i].name,L->elem[i].price);
}
}
5.结论
表长减1的操作会同时释放表尾存储空间



