【问题标题】:What's the reason of the linked list has a zero beginning of the beginning? C++链表开头的开头为零的原因是什么? C++
【发布时间】:2018-06-04 14:02:54
【问题描述】:
#include <iostream>    

using namespace std;

struct Node {
    int data;
    Node* next;
};

void add(struct Node *head, int n) {
    Node *newNode = new Node;
    newNode->data = n;
    newNode->next = NULL;
    Node *cur = head;
    while(cur) {
        if(cur->next == NULL) {
            cur->next = newNode;
            return;
        }

        cur = cur->next;
    }
}

void display(struct Node *head) {
    Node *list = head;
    while(list) {
        cout << list->data << " ";
        list = list->next;
    }
    cout << endl;
    cout << endl;
}

int main()
{
    struct Node *newHead;
    struct Node *head = new Node;
    int ar[]={2,5,46,7,55};
    for(int i=0; i<5;i++){
        add(head,ar[i]);
    }
    display(head);
}

输出:

0 2 5 46 7 55

链表开头为零的原因是什么? 我该如何解决?我不想打印零。

如果您在我的代码中发现一些错误,请告诉我。我是编码新手。

【问题讨论】:

  • head 也有一个未初始化的值。
  • 在将 struct 命名为 c++ 中的类型之前,您无需指定 structstruct 是隐含的类型名称。
  • struct Node *head = new Node; 您正在将一个具有未初始化值(您的编译器足以使其为 0)的节点添加到列表的开头。
  • 你的老师好像还停留在90年代。您应该用一本好的 C++ 书籍来补充该课程。

标签: c++ linked-list output nodes


【解决方案1】:

main 中,您分配Node 的未初始化实例并将指针存储在head 中。您永远不会分配该节点的head-&gt;data,因此该值是不确定的。 head-&gt;next 也是如此。在adddisplay 中读取这些值时,程序的行为是未定义的。


我该如何解决?

首先,在main 中初始化head 以避免未定义的行为:

Node *head = new Node();
//                   ^^ these are important

然后你可以做以下事情之一:

a) 使用display(head-&gt;next); 而不是display(head); 跳过第一个节点

b) 将head 初始化为您想要的第一个值

head->data = ar[0];
for(int i=1; i<5;i++)
// ...

c) 重新设计您的 API 以不要求用户单独分配第一个节点。 Remy 的回答中对此有更多详细信息。

【讨论】:

    【解决方案2】:

    你的代码有几个问题:

      1234563而且您也没有初始化其next 成员,这意味着add()display() 将无法正常工作。
    1. add() 中,如果head 为NULL,则不会将节点添加到列表中(您不会更新调用者的Node* 变量以指向新节点),并且您会泄漏分配的newNode

    2. main() 退出时,您正在泄漏所有已分配的节点。

    试试这个:

    #include <iostream>    
    
    struct Node {
        int data;
        Node* next;
        Node(int value) : data(value), next(0) {}
    };
    
    void add(Node* &head, int n) {
        Node **newNode = &head;
        while (*newNode) {
            newNode = &((*newNode)->next);
        }
        *newNode = new Node(n);
    }
    
    void display(Node *head) {
        Node *cur = head;
        while (cur) {
            std::cout << cur->data << " ";
            cur = cur->next;
        }
        std::cout << std::endl;
        std::cout << std::endl;
    }
    
    void clear(Node* &head) {
        Node *cur = head;
        head = NULL;
        while (cur) {
            Node *next = cur->next;
            delete cur;
            cur = next;
        }
    }
    
    int main()
    {
        Node *head = NULL;
        int ar[] = {2, 5, 46, 7, 55};
        for(int i = 0; i < 5; ++i){
            add(head, ar[i]);
        }
        display(head);
        clear(head);
        return 0;
    }
    

    然后,当你开始工作时,把它全部扔掉,改用 STL 的 std::list 容器:

    #include <iostream>
    #include <list>
    
    void display(const std::list<int> &mylist) {
        for(std::list<int>::const_iterator iter = mylist.begin(); iter != mylist.end(); ++iter) {
            std::cout << *iter << " ";
        }
        std::cout << std::endl;
        std::cout << std::endl;
    }
    
    int main()
    {
        std::list<int> mylist;
        int ar[] = {2, 5, 46, 7, 55};
        for(int i = 0; i < 5; ++i){
            mylist.push_back(ar[i]);
        }
    
        /* or:
        int ar[] = {2, 5, 46, 7, 55};
        std::list<int> mylist(ar, ar+5);
        */
    
        display(mylist);
        return 0;
    }
    

    【讨论】:

    • 天哪,head 的另一个间接级别?通过引用传递不是更容易吗?
    • @scohe001:当用作函数参数时,引用仍然是间接的。无论如何,大多数编译器都使用指针来实现引用。但无论如何,我更新了我的示例。
    猜你喜欢
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    相关资源
    最近更新 更多