提问人:Pain 提问时间:10/8/2023 最后编辑:Pain 更新时间:10/8/2023 访问量:102
单向链表 с++ 的问题
The problem with a singly linked list с++
问:
我有一个执行以下任务的代码:将字符逐行输入到点上,然后显示一个列表。我需要添加这样一个方法,以便在调用它时,列表以相反的顺序补充其所有字符(例如,有一个 abс. 列表应该变成 abс.сba)。您无法展开该列表。该方法应基于此原则:我们从第一个元素再次浏览列表,每次在该点后添加一个元素(首先是 abс.a,然后是 abс.ba,然后是 abс.сba)。我试图编写 Add Elements 函数,但我最终对它感到困惑,或者我捕获了一个输出为空的无限循环,反之亦然,输出无限,或者只输出第一个字符
这是我的代码
#include <iostream>
#include <windows.h>
struct element {
char x;
element* Next;
};
class List {
element* Head;
public:
List() {
Head = NULL;
}
~List();
void Add(char x, element*& Head);
void Show(element* Beg);
void AddElements(element* beg, element*& Head);
};
List::~List() {
while (Head != NULL) {
element* temp = Head->Next;
delete Head;
Head = temp;
}
}
void List::Add(char x, element*& Head) {
element* temp = new element;
temp->x = x;
temp->Next = NULL;
Head->Next = temp;
Head = temp;
}
void List::Show(element* beg) {
element* temp = beg;
while(temp != NULL) {
std::cout << temp->x << "";
temp = temp->Next;
}
Head = beg;
}
void List::AddElements(element* beg, element*& Head) {
element* temp1 = beg;
element* temp2 = Head;
element* temp0 = temp1;
temp2->Next = temp0;
while (temp1 != temp2) {
temp0->Next = temp2->Next;
temp0 = temp1;
temp2->Next = temp0;
if (temp1->Next != NULL) {
temp1 = temp1->Next;
}
}
}
int main() {
system("chcp 1251");
std::cout << "Односвязный список." << std::endl;
char x;
List lst;
element* H = new element;
element* beg = H;
std::cout << "Введите символ: "; std::cin >> x;
H->x = x;
H->Next = NULL;
while (x != '.') {
std::cin >> x;
lst.Add(x, H);
}
lst.AddElements(beg, H);
std::cout << "Результат: ";
lst.Show(beg);
return 0;
}
我希望从abs列表中创建一个函数,该函数将创建一个abс.сba列表并输出它(
答:
0赞
Kozydot
10/8/2023
#1
您遇到的问题似乎是由于在方法中对链表的错误操作造成的。AddElements
任务是颠倒字符的顺序并将它们添加到列表的末尾。这可以通过遍历列表,将字符存储在堆栈中,然后将堆栈中的反转字符填充回列表中来实现。
void List::AddElements(element* beg) {
std::stack<char> s;
element* temp = beg;
while(temp != NULL) {
s.push(temp->x);
temp = temp->Next;
}
while(!s.empty()) {
Add(s.top(), Head);
s.pop();
}
}
这是正在发生的事情:
- 从头到尾遍历列表,将每个字符推到堆栈上。这是因为堆栈遵循后进先出 (LIFO) 协议,这意味着添加的最后一个元素将是第一个要删除的元素。这本质上颠倒了字符的顺序。
- 从堆栈中弹出每个字符并将其添加到列表末尾
使用方法。
Add
评论
0赞
Pain
10/8/2023
我尝试了您的方法,在第 35 行(Add 方法的说明)中引发了异常:Project2 中地址0x004A5818未处理的异常.exe:0xC0000005:写入地址0x00000004时访问冲突。
0赞
PaulMcKenzie
10/9/2023
@Pain 你应该检查你要传递给什么。如果答案中给出的代码是正确实现的列表,则必须正常工作。这意味着您应该使用调试器查看 、 、 等,以确保它已正确构建。唯一的另一种可能性是坏了,或者被搞砸了(这意味着坏了)。AddElements
beg
beg
beg->Next
beg->Next->Next
Add
Head
Add
Add
0赞
Pain
10/9/2023
@PaulMcKenzie好的,谢谢,我稍后会在调试器中尝试,只是没有 Addelement 函数,一切正常,并输出列表。使用此函数时,会发生异常,即在某些迭代中 temp 为 NULL,并且程序关闭
上一个:从末尾找到第 k 个节点
评论
for (auto i = 0; i < 10; i++) {
while (temp) {
Head