单向链表 с++ 的问题

The problem with a singly linked list с++

提问人:Pain 提问时间:10/8/2023 最后编辑:Pain 更新时间:10/8/2023 访问量:102

问:

我有一个执行以下任务的代码:将字符逐行输入到点上,然后显示一个列表。我需要添加这样一个方法,以便在调用它时,列表以相反的顺序补充其所有字符(例如,有一个 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列表并输出它(

C++ 单向链接列表

评论

0赞 drescherjm 10/8/2023
你的 show 函数不应该有:相反,你需要循环for (auto i = 0; i < 10; i++) {while (temp) {
1赞 Vlad from Moscow 10/8/2023
@Pain “您无法展开列表”,这与任务描述相矛盾:)
1赞 BoP 10/8/2023
您似乎有两个指针,一个作为成员,一个作为参数。你可能应该只有一个。Head
1赞 Some programmer dude 10/8/2023
您似乎错过了类中成员变量的要点。不要创建单独的“头”,不要将其传递给函数。
0赞 Vlad from Moscow 10/8/2023
@Pain 在这种情况下,定义一个双侧单向链表会好得多。

答:

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 你应该检查你要传递给什么。如果答案中给出的代码是正确实现的列表,则必须正常工作。这意味着您应该使用调试器查看 、 、 等,以确保它已正确构建。唯一的另一种可能性是坏了,或者被搞砸了(这意味着坏了)。AddElementsbegbegbeg->Nextbeg->Next->NextAddHeadAddAdd
0赞 Pain 10/9/2023
@PaulMcKenzie好的,谢谢,我稍后会在调试器中尝试,只是没有 Addelement 函数,一切正常,并输出列表。使用此函数时,会发生异常,即在某些迭代中 temp 为 NULL,并且程序关闭