题目:将顺序表中元素值为x的删除并输出删除之后的表;
问题:为什么感觉逻辑上没错,删除元素会出现删不干净呢?
#include<stdlib.h>
#include<stdio.h>
# define Maxsize 100
# define ElemType int
# define Status int
//结构
typedef struct {
ElemType* elem;
int length;
int listsize;
}SqList;
//初始化
Status InitList(SqList& L)
{
L.elem = (ElemType*)malloc(Maxsize * sizeof(ElemType));
if (!L.elem) return false;
L.length = 0;
L.listsize = Maxsize;
return true;
}
//输入数据
Status Enter(SqList& L, int n)
{
for (int i = 0; i < n; i++)
{
scanf_s("%d", &(L.elem[i]));
L.length++;
}
return true;
}
//输出数据
Status Out(SqList& L)
{
if (!L.elem)
return false;
for (int i = 0; i < L.length; i++)
printf("%d ", L.elem[i]);
return true;
}
Status Handle(SqList& L)
{
int j = 0, a[20];
for (int i = 0; i < L.length; i++)
{
if (L.elem[i] == 7)
{
a[j] = i;
j++;
}
}
for (int m = 0; m < j; m++)
{
int* p = &(L.elem[a[m]]);
int e = *p;
int* q = L.elem + L.length - 1;
for (++p; p <= q; ++p) *(p - 1) = *p;
--L.length;
}
return true;
}
int main()
{
SqList L;
InitList(L);
int n;
printf("输入数据的规模:");
scanf_s("%d", &n);
printf("输入数据:");
Enter(L, n);
printf("原先的数据:");
Out(L);
Handle(L);
printf("\n经过删除x=7后的数据:");
Out(L);
return 0;
}
删除里,算法设计有问题的,当找到待删除的位置存放在a[]数组里。然后下面开始删除a[0]第一个位置后,表长度减一 --L.length; ,表往前移一位,再删第二位置即a[1] 时记录的是原长度的下标值,与前移一次的位置就不对应了,错位了。将第53行的代码:int* p = &(L.elem[a[m]]); 修改为:
int* p = &(L.elem[a[m] - m]); ,即可,供参考:
#include<stdlib.h>
#include<stdio.h>
# define Maxsize 100
# define ElemType int
# define Status int
//结构
typedef struct {
ElemType* elem;
int length;
int listsize;
}SqList;
//初始化
Status InitList(SqList& L)
{
L.elem = (ElemType*)malloc(Maxsize * sizeof(ElemType));
if (!L.elem) return false;
L.length = 0;
L.listsize = Maxsize;
return true;
}
//输入数据
Status Enter(SqList& L, int n)
{
for (int i = 0; i < n; i++)
{
scanf_s("%d", &(L.elem[i]));
L.length++;
}
return true;
}
//输出数据
Status Out(SqList& L)
{
if (!L.elem)
return false;
for (int i = 0; i < L.length; i++)
printf("%d ", L.elem[i]);
return true;
}
Status Handle(SqList& L)
{
int j = 0, a[20];
for (int i = 0; i < L.length; i++)
{
if (L.elem[i] == 7)
{
a[j] = i;
j++;
}
}
for (int m = 0; m < j; m++)
{
int* p = &(L.elem[a[m] - m]); //int* p = &(L.elem[a[m]]); 修改
int e = *p;
int* q = L.elem + L.length - 1;
for (++p; p <= q; ++p) *(p - 1) = *p;
--L.length;
}
return true;
}
int main()
{
SqList L;
InitList(L);
int n;
printf("输入数据的规模:");
scanf_s("%d", &n);
printf("输入数据:");
Enter(L, n);
printf("原先的数据:");
Out(L);
Handle(L);
printf("\n经过删除x=7后的数据:");
Out(L);
return 0;
}
建议将删除函数换种写法,供参考:
Status Handle(SqList& L)
{
int j = 0, x = 7;
for (int i = 0; i < L.length; i++)
{
if (L.elem[i] - x)
L.elem[j++] = L.elem[i];
}
L.length = j;
return true;
}
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
在你的代码中,删除元素的逻辑上是正确的。但是在实际情况中,可能会出现删除不完全的情况,这是由于你删除元素时,只删除了第一个找到的元素,而没有考虑到顺序表中可能存在多个相同的元素。
例如,如果顺序表中有如下元素序列:{7, 2, 7, 8, 7, 6, 7},且要删除的元素值为7,则你的程序只会删除第一个找到的7,结果为{2, 7, 8, 7, 6, 7},而实际上还有两个7没有被删除。
因此,你需要修改代码,考虑到顺序表中可能存在多个相同的元素。可以使用一个循环,每次找到一个需要删除的元素时,就把它后面的元素依次往前移动一个位置,直到把所有的需要删除的元素都删除为止。修改后的代码如下:
Status Handle(SqList& L, ElemType x)
{
int k = 0; // 记录已删除的元素个数
for (int i = 0; i < L.length - k; i++)
{
if (L.elem[i] == x)
{
k++;
for (int j = i; j < L.length - k; j++)
{
L.elem[j] = L.elem[j + 1];
}
i--; // 因为元素往前移了一位,所以需要将i回退一位
}
}
L.length -= k; // 更新顺序表的长度
return true;
}
在这个修改后的代码中,我们使用一个变量k来记录已经删除的元素个数,每次删除一个元素后,都将k加1。在循环中,我们从第一个元素开始遍历,如果找到一个需要删除的元素,就将后面的元素依次往前移动一个位置,直到移动到顺序表的末尾。因为每次删除一个元素后,顺序表的长度会减少1,所以我们需要在循环结束后,更新顺序表的长度。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
容易犯错的地方:
思考为何不先增表长,再后移再插入x