请教一下这个数据结构算法题
题目:在带头结点的单链表L中,删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一,试编写算法实现上述操作问题/疑惑:我使用的编译器为vs2022,程序编译运行之后没有输出删除元素x后的链表元素,程序没有报错,我重复看了几遍代码也没找出问题,望大佬指点一下,告诉我怎么改这一段代码才正确??
代码如下:
#include <iostream>
#include<stdlib.h>
using namespace std;
#define MAX 50
typedef struct LNode
{
int data;
struct LNode* next;
}LNode, * Linklist;
int a = { 1,3,3,4 };
int length = 4;
void buildlist(Linklist& L)//把数组中的值放入新建的链表中
{
L = (LNode*)malloc(sizeof(LNode));
LNode* s, * r = L;
for (int i = 0; i < length; i++)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = a;
r->next = s;
r = r->next;
}
}
void disp(Linklist L)//输出链表的值
{
LNode* s = L->next;
while (s)
{
cout << s->data;
s = s->next;
}
}
void deletex(Linklist& L, int x)//删除所有为x的元素
{
LNode* p = L->next, * r = L, * q;
while (p)
{
if (p->data != x)
{
r->next = p;
r = p;
p = p->next;
}
else
{
q = p;
p = p->next;
r->next = p;
free(q);
}
}
}
int main()
{
Linklist L;
buildlist(L);
cout << "删除前的链表为:" << endl;
disp(L);
cout << "删除后的链表为:" << endl;
deletex(L, 3);
disp(L);
} 您好!根据您提供的代码,我发现您在 buildlist 函数中遗漏了一步:在循环结束后,需要将链表的最后一个结点的 next 指针设置为 NULL 。这样,当我们遍历链表时,就能找到链表的末尾。请参考下面的修改后的代码:
#include <iostream>
#include<stdlib.h>
using namespace std;
#define MAX 50
typedef struct LNode
{
int data;
struct LNode* next;
}LNode, * Linklist;
int a = { 1,3,3,4 };
int length = 4;
void buildlist(Linklist& L)//把数组中的值放入新建的链表中
{
L = (LNode*)malloc(sizeof(LNode));
LNode* s, * r = L;
for (int i = 0; i < length; i++)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = a;
r->next = s;
r = r->next;
}
r->next = NULL; // 添加这一行代码
}
void disp(Linklist L)//输出链表的值
{
LNode* s = L->next;
while (s)
{
cout << s->data << " "; // 添加一个空格,使输出更易于阅读
s = s->next;
}
cout << endl; // 输出换行,使结果更易于阅读
}
void deletex(Linklist& L, int x)//删除所有为x的元素
{
LNode* p = L->next, * r = L, * q;
while (p)
{
if (p->data != x)
{
r->next = p;
r = p;
p = p->next;
}
else
{
q = p;
p = p->next;
r->next = p;
free(q);
}
}
}
int main()
{
Linklist L;
buildlist(L);
cout << "删除前的链表为:" << endl;
disp(L);
cout << "删除后的链表为:" << endl;
deletex(L, 3);
disp(L);
}
在这个修改后的代码中,我添加了一行代码( r->next = NULL; )以在 buildlist 函数中设置链表的末尾。另外,我还对 disp 函数进行了轻微修改,使输出结果更易于阅读。现在这个代码应该可以按照预期运行,正确输出删除元素x后的链表元素。 你的代码在函数deletex()中,当p指针指向值为x的结点时,没有更新r的值,导致新的结点插入到了上一个不为x的结点的后面,而不是插入到链表中,因此程序没有输出正确的链表元素。
你需要在p指向的结点的值不为x时,更新r的值。修改deletex()函数如下:
void deletex(Linklist& L, int x)
{
LNode* p = L->next, * r = L, * q;
while (p)
{
if (p->data != x)
{
r = p;
p = p->next;
}
else
{
q = p;
p = p->next;
r->next = p;
free(q);
}
}
}
请注意,这里是在p指向的结点的值不为x时,更新r的值,而不是在p指向的结点的值为x时更新r的值。这样可以保证当找到值为x的结点时,r指向的是上一个不为x的结点,方便后续删除操作。
修改后,你可以重新编译运行程序,并查看输出结果。
根据你给出的代码,存在以下问题:
1. 在 `buildlist` 函数中,没有将最后一个结点的 next 置为 NULL,使得在后面遍历链表时,会遍历到一些未知区域,可能导致程序出错。
2. 在 `deletex` 函数中,当需要删除值为 x 的结点时,没有更新 r 的指向,使得在下一次循环迭代中,r 和 p 间隔了一个值为 x 的结点。这个问题可以通过在 if 语句块开始处新增 else if (p->next == NULL) { r = p; break; } 来解决,在判断当前结点是否是需要删除的结点时,如果是最后一个结点,则需要令 r 指向它,然后跳出循环。
修改后的代码如下:
void buildlist(Linklist& L)//把数组中的值放入新建的链表中
{
L = (LNode*)malloc(sizeof(LNode));
LNode* s, * r = L;
for (int i = 0; i < length; i++)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = a;
r->next = s;
r = s;
}
r->next = NULL; // 将最后一个结点的 next 置为 NULL
}
void deletex(Linklist& L, int x)//删除所有为x的元素
{
LNode* p = L->next, * r = L, * q;
while (p)
{
if (p->data != x)
{
r->next = p;
r = p;
p = p->next;
}
else
{
q = p;
p = p->next;
r->next = p;
free(q);
}
// 新增代码,判断是否需要更新 r
if (p == NULL) { r = p; break; }
}
}
你可以试着编译并运行一下这份代码
有用请设置最佳答案 sfqxx 发表于 2023-5-2 11:27
根据你给出的代码,存在以下问题:
1. 在 `buildlist` 函数中,没有将最后一个结点的 next 置为 NULL, ...
谢谢捏!
页:
[1]