c++ 链接列表不打印输出

k10s72fa  于 2022-11-19  发布在  其他
关注(0)|答案(1)|浏览(351)

我必须为一个学校项目动态分配一个机器人列表。在一个实际的程序中,会有其他成员函数需要名称列表才能执行某些函数。
到目前为止,我刚刚了解到这个概念,并且已经非常努力地把我在网上看到的一些东西放在一起。目前的问题是,我不能判断我的列表是否被正确存储--当我试图调用我的列表显示函数时,我也得到了不稳定的输出。
请帮助,如果你可以的话。而且,我很高兴听到任何提示字面上的任何东西,因为我是相当新的编程。

class Node{
public:
    std::string name_;
    Node* next;
};

class linkedBotList{
public:
    
    linkedBotList() {head = nullptr;} //constructor
    ~linkedBotList(){}; // destructure
    
    void addNode();
    void display();

private:
    Node* head;   
};

int main(int argc, const char * argv[]) {
    linkedBotList* list = new linkedBotList();
    int siz;
    
    std::cout << "How many Robots?" << std::endl;
    std::cout << "What are the names?" << std::endl;
    std::cin >> siz;
    for(int i = 0; i < siz; i++){
        list->addNode();
    }
    delete list;
    return 0;
}

void linkedBotList::addNode(){
    std::string botName;
    Node* newNode = new Node();
    newNode->name_ = botName;
    newNode->next = nullptr;
    
    std::cin >> botName;
    
    if(head == nullptr){
        head = newNode;
    }
    else {
        Node* temp = head; // head is not null
        while(temp->next != nullptr){ // go until at the end of the list
            temp = temp->next;
        }
        temp->next = new Node; // linking to new node
    }
}

void linkedBotList::display() {
   
    if (head == NULL) {
        std::cout << "List is empty!" << std::endl;
    }
    else {
        Node* temp = head;
        while (temp != NULL) {
            std::cout << "Made it to display funct.\n";
            std::cout << temp->name_ << " ";
            temp = temp->next;
        }
        std::cout << std::endl;
    }
}

我确实尝试了一些方法,比如改变我的temp变量,以及一些其他的重新赋值。也许有人能很快发现问题并提供帮助?

bpzcxfmw

bpzcxfmw1#

显示功能正常。
问题是addNode()中有两个逻辑缺陷:

  • 您没有在列表中正确存储字符串。您在botName赋值之前将botName赋值给newNode->name_。因此,所有节点都有空字符串。之后赋值botName将不会更新newNode->name_。1
  • 如果列表不是空的,你可以正确地迭代到列表的末尾2,但是你给temp->next赋了一个新的空节点,而不是给你已经填充的newNode赋值,而且你的Node构造函数没有把next成员初始化为nullptr,所以你创建了一个损坏的列表,这将导致通过列表的后续循环调用 undefined behavior

请尝试以下操作:

void linkedBotList::addNode(){
    std::string botName;    
    std::cin >> botName; // <-- move up here
    
    Node* newNode = new Node{botName, nullptr};

    if (!head){
        head = newNode;
    }
    else {
        Node* temp = head;
        while (temp->next){
            temp = temp->next;
        }
        temp->next = newNode; // <-- linking to new node
    }
}

或者,您也可以像这样删除if

void linkedBotList::addNode(){
    std::string botName;    
    std::cin >> botName;

    Node** temp = &head;
    while (*temp){
        temp = &((*temp)->next);
    }

    *temp = new Node{botName, nullptr};
}

1:更好的设计是让addNode()接受string作为输入参数,然后将cin调用移到main()中的循环中。
2:考虑向列表中添加一个tail成员,以避免每次添加时都必须循环。
尝试以下替代设计:

class Node{
public:
    std::string name;
    Node* next = nullptr;
};

class linkedBotList{
public:
    
    linkedBotList() = default;
    ~linkedBotList();
    
    void addNode(std::string name);
    void display() const;

private:
    Node* head = nullptr;
    Node* tail = nullptr;  
};

int main() {
    linkedBotList list;
    int siz;
    std::string botName;
    
    std::cout << "How many Robots?" << std::endl;
    std::cin >> siz;

    std::cout << "What are the names?" << std::endl;
    for(int i = 0; i < siz; i++){
        std::cin >> botName;
        list.addNode(botName);
    }

    list.display();
    return 0;
}

linkedBotList::~linkedBotList(){
    Node *temp = head, *next;
    while (temp) {
        next = temp->next;
        delete temp;
        temp = next;
    }
}

void linkedBotList::addNode(std::string name){
    Node* newNode = new Node{name};    
    if (tail)
        tail->next = newNode;
    else
        head = newNode;
    tail = newNode;
}

void linkedBotList::display() const {
    if (!head) {
        std::cout << "List is empty!" << std::endl;
    }
    else {
        Node* temp = head;
        do {
            std::cout << temp->name << " ";
            temp = temp->next;
        }
        while (temp);
        std::cout << std::endl;
    }
}

相关问题