删除顺序表中 与输入的元素相同的所有元素问题
双指针实现;
/*
TODO: 删除表中与Item值相同的元素
功能:从键盘输入一个整数item,删除表中与Item数字相同的元素
比如:表为:6 5 4 3 2 1,录入2,则删除2,新的顺序表为:6 5 4 3 1
参数:List *L 是需要操作的表,item是指定删除元素的数值
返回值:空
*/
typedef struct Sq {
int elem[MAX] ;int length ; //长度;
} List;
void Delete(List *L , int item){
int *p1,*p2; int i=L->length;
p1= &L->elem[0], p2=&L->elem[L->length];
//统计顺序表中为item的总共个数;
while(i!=-1)
{
if(L->elem[i]==item)
{
L->length--;
}
i--;
}
while(1)
{
if( *p1==item )
{
while(*p2==item)//当遇到 *p1==item && *p2==item 移动*p2 ;
{
p2++;
}
*p1=*p2 ;
if(p1+sizeof(int)==p2) //相遇时;
{
break;
}
p2++;
p1++;
}
else
p1++;
}
}
当输入遇到 0 +回车时输入结束;
为什么 无法达到 删除相同的item ? 而且输出中总是有未知的值 ?
希望帮忙解答一下;
输出示例;
回答:
p2=&L->elem[L->length]
内存访问越界了,最后一个数是L->elem[L->length-1]
- 既然p2已经指向末尾了,后文中的
p2++;
多次越界 int *p1,*p2
,指针是int型,数组也是int型,p1 + 1就是访问下一个元素了,p1+sizeof(int)
等于p1+4
,所以用p1+sizeof(int)==p2)
去判断相遇是不对的- 逻辑考虑不周全,当6 5 4 3 2 1中的3被删掉后,后面的2 1没有向前搬运
追加内容
你的思路可以解题,只是把问题复杂化了。
我有个简洁的思路你参考一下
#include <stdio.h>#define MAX 10
typedef struct Sq {
int elem[MAX];
int length;
} List;
void Delete(List *L , int item) {
int *p1, *p2;
int len = L->length;
p1 = &L->elem[0]; // p1 指向数组开头
for (p2 = p1; p2 < (L->elem + len); p2++) { // 用p2遍历整个数组
if (*p2 != item) { // 检查数据合法
*p1++ = *p2; // 将合法数据搬运到p1,并且p1移位,准备下次接收
} else {
L->length--; // 舍弃不合法的数据,并将数组长度减短
}
}
}
// 测试函数
void test(int del_num) {
List L = {{3,2,3,3,1,1}, 6};
printf("-------------------\n");
printf("input array:");
for (int i = 0; i < L.length; i++) {
printf("%d ", L.elem[i]);
}
printf("\n");
Delete(&L, del_num);
printf("delete num:%d\noutput array:", del_num);
for (int i = 0; i < L.length; i++) {
printf("%d ", L.elem[i]);
}
printf("\n");
}
int main() {
test(3);
test(2);
test(1);
test(0);
}
输出
-------------------input array:3 2 3 3 1 1
delete num:3
output array:2 1 1
-------------------
input array:3 2 3 3 1 1
delete num:2
output array:3 3 3 1 1
-------------------
input array:3 2 3 3 1 1
delete num:1
output array:3 2 3 3
-------------------
input array:3 2 3 3 1 1
delete num:0
output array:3 2 3 3 1 1
回答:
还有一个问题应该使用p1<p2;作为判段相交的条件
void Delete(List *L , int item){
int *p1,*p2; int i=L->length;
p1= &L->elem[0], p2=&L->elem[L->length];
//统计顺序表中为item的总共个数;
while(i!=-1)
{
if(L->elem[i]==item)
{
L->length--;
}
i--;
}
while(p1<p2)
{
if(*p1==item)
{
if(*p2==item)
while(*p2==item)
p2--;
*p1=*p2;
p2--;
p1++;
}
else
p1++;
}
}
以上是 删除顺序表中 与输入的元素相同的所有元素问题 的全部内容, 来源链接: utcz.com/p/194972.html