#define OK 1 // 宏定义, 下同
#define ERROR -1
#define MAX_SIZE 100
typedef int Status ; // 类型别名,下同
typedef int ElemType ;
typedef struct sqlist
{
ElemType Elem_array[MAX_SIZE]; // 存储元素
int length; // 线性列表中元素的个数
} SqList ;
/* L 是目标线性列表,x 是需要删除的元素 */
Status Locate_Delete_SqList(Sqlist *L,ElemType x)
{
int i = 0 , k;
bool del = false;
while (i < L->length)
{
/* 遍历线性列表中的每个元素,如果没有找到 x 元素,则一直往后找(i++)
当找到 x 元素时,则进入else分支,开始执行删除步骤,删除后跳出循环*/
if (L->Elem_array[i] != x)
i++;
else
{
/* 将 x 后面的元素都向前挪一位,这样就可以填补删除 x 的空白。
例如: 1 2 3 4 删除 2,其实就是让 3, 4 前移,挤掉 2 的位置 */
for ( k=i+1; k< L->length; k++)
L->Elem_array[k-1]=L->Elem_array[k];
L->length--; // 删除之后,元素个数减1
del = true;
break ; // 删除结束,跳出循环
}
}
// 由前面的过程可以看出,i 要么停留在 x 所在的位置,要么直接跑到列表的尾部。
// 如果列表中不存在 x,则 i 一直++到 i == L->length 并跳出循环。
if (!del)
{
printf(“要删除的数据元素不存在!\n”) ;
return ERROR ;
}
return OK;
}
我个人感觉 if (i > L->length) 用来判断 x 不存在,不是很合适。
比如 1 2 3,如果是 x = 4,由于列表中没有4, 因而i会递增到 i == L->length,也就是 3。根据原来的判断,if (i > L->length) ,明显不会进入 if 分支,而会提示删除成功,这是不正确的。而改为 if (i == L->length) 也不行,因为如果 x = 3 的话,i 递增到了2, 删除 3 之后 L->length 也是 2,会进入 if分支并提示元素不存在。这个同样不科学。
通过标记位的方式就可以避免这些问题了。