删除顺序表中 与输入的元素相同的所有元素问题

双指针实现;
/*
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 ? 而且输出中总是有未知的值 ?
希望帮忙解答一下;
输出示例;
QQ图片20200317230502.png

回答:

  1. p2=&L->elem[L->length]内存访问越界了,最后一个数是L->elem[L->length-1]

  2. 既然p2已经指向末尾了,后文中的p2++;多次越界
  3. int *p1,*p2,指针是int型,数组也是int型,p1 + 1就是访问下一个元素了,p1+sizeof(int)等于p1+4,所以用p1+sizeof(int)==p2)去判断相遇是不对的

  4. 逻辑考虑不周全,当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

回到顶部