我如何在c ++中附加结构Person

时间:2014-09-23 21:31:10

标签: c++ pointers struct

我有struct Person

struct Person {
    string name;
    int age;
    Person* next;
};

我需要创建一个函数,将结构彼此追加,就像链表一样。我开始创建一个指针头,它在开头是一个空指针。

using namespace std;
Person* head = nullptr;

void append(Person*& list, const string& name, int age) {
    auto p = new Person{name, age, nullptr}; // typ List_Node*
    if (list == nullptr) {
        list = p;
        return;
    }

    auto last = list;
    while (last != nullptr) {
        last = last->next;
    }
    last = p;
}

int main() {
    append(head, "First_Person", 21);
    append(head, "Second_Person", 22);
    // testing the result
    head = head->next;
    cout << "head->name outside: " << head->name << endl;
    return 0;
}

现在我遇到的问题是,在第一次追加后append()函数似乎没有将第一个人链接到第二个人,因为程序崩溃了

head = head->next;

问题是:如何让append()在这个链表上附加1个以上的人?

3 个答案:

答案 0 :(得分:1)

    auto last = list;
    while (last != nullptr){
        last = last->next;
    }
    last = p;

当您离开此循环时,last再次指向nullptr而不是列表的最后一个元素。您需要检查last->next != nullptr

此外,last = p没有做任何有用的事情;它应该是last->next = p,以便将p实际附加到列表中。

答案 1 :(得分:0)

您的append()未正确管理指针。试试这个:

void append(Person*& list, const string& name, int age)
{
    auto p = new Person{name, age, nullptr}; // typ List_Node*

    if (list == nullptr)
    {
        list = p;
        return;
    }

    auto last = list;
    while (last->next != nullptr)
        last = last->next;

    last->next = p;
}

如果你摆脱了list参数,你可以避免在每个追加上遍历整个列表

Person* head = nullptr;
Person* last = nullptr;

void append(const string& name, int age)
{
    auto p = new Person{name, age, nullptr};

    if (head == nullptr)
        head = p;

    if (last != nullptr)
        last->next = p;

    last = p;
}

int main()
{
    append("First_Person", 21);
    append("Second_Person", 22);

    //testing the result
    for(Person *p = head; p != nullptr; p = p->next)
        std::cout << "name: " << p->name << std::endl;

    // free the list
    Person *p = head;
    while (p != nullptr)
    {
        Person *next = p->next;
        delete p;
        p = next;
    }

    return 0;
}

话虽如此,您应该使用std::liststd::forward_list来保存您的Person项目并让它为您处理所有这些细节,例如:

#include <list> // or: #include <forward_list>

struct Person
{
    string name;
    int age;
};

std::list<Person> mylist; // or: std::forward_list<Person> mylist;

void append(const string& name, int age)
{
    mylist.push_back(Person{name, age});
}

int main()
{
    append("First_Person", 21);
    append("Second_Person", 22);

    //testing the result
    for (auto &person: mylist)
        std::cout << "name: " << person.name << std::endl;

    return 0;
}

答案 2 :(得分:0)

如果你是在非学术背景下写这篇文章,那就不要重新发明轮子,并使用像矢量或列表这样的标准容器。

然而,假设练习的目的是学习数据结构,那么使用内置容器并不会教你太多。

我看到的问题是你什么也没做,只是改变了“最后”指针,它实际上并没有追加任何东西到列表中。您需要首先找到最后一个节点(通过使用'last'指针移动到每个节点 - >接下来,直到您到达一个具有null的节点 - >下一个指针。然后在您的旁边分配该节点的 - &gt;新节点。

您现有的代码......

// Already handled empty list case before we get here...

auto last = list;  // last pointer set to address list (head)
while (last != nullptr){    // while not at end of list, last points to next node
    last = last->next;
}
                   // after loop, last will always be null, not very useful
last = p;          // last points to p (the new node) which doesn't _do_ anything

考虑做以下事情:

// Already handled empty list case before we get here...

auto last = list;  // last pointer set to address list (head)
while (last && last->next != nullptr){    // while node->next not null, move to next node
    last = last->next;
}
                   // at end of list, last will always point to last node
last->next = p;    // link last->next to the new 'p' Person

请记住,如果你做了很多列表追加操作,你的列表数据结构保持头部和尾部指针会更便宜,并且简单地追加

if(tail)
    tail->next = p;
tail = p;

除此之外,在列表的头部插入项目会更便宜。

p->next = head;
head = p;