为什么它只打印双向链表的第一个值,而我的程序却崩溃了

Why it is printing only 1st value of doubly linked list and than my program is crashing

我试图创建一个双向链表,然后打印它的值,但输出只显示第一个值,然后整个程序崩溃了。

我看不懂代码哪里有问题。

输入

3

1 2 3

预期产出

1 2 3

当前输出

1

#include<iostream>
#include<stdlib.h>
using namespace std;
class node                                  //declation of node
{
public:
    int data;
    node *next;
    node *prev;
};
node *makenode(node *head,int val)          //function to create node
{
    node *newnode=new node;
    node *temp;
    newnode->data=val;
    newnode->next=0;
    newnode->prev=0;
    if(head==0) temp=head=newnode;

    else
    {
        temp->next=newnode;
        newnode->prev=temp;
        temp=newnode;
    }
    return head;
}
void display(node *head)                     //display function
{
    system("cls");                          //clearing output screen
    while(head!=0)
    {
        cout<<head->data<<"  ";
        head=head->next;
    }
}
int main()
{
    node *head;
    head=0;
    int val;
    int s;                                   //size of list
    cout<<"ENTER THE SIZE OF LIST";
    cin>>s;
    system("cls");
    for(int i=0;i<s;i++)
    {
        cout<<"ENTER THE "<<i+1<<" VALUE\n";
        cin>>val;
        head=makenode(head,val);             //calling makenode and putting value
    }
    display(head);                           //printing value
    return 0;

}
node *makenode(node *head,int val)          //function to create node
{
    node *newnode=new node;
    node *temp;               // #1
    newnode->data=val;
    newnode->next=0;
    newnode->prev=0;
    if(head==0) temp=head=newnode;

    else
    {
        temp->next=newnode;   // #2

在上面标记为 #1#2 的行之间,究竟是什么将变量 temp 设置为指向实际的 节点 而不是而不是指向某个任意内存地址?

“没什么”,我听到你说?好吧,那将是一个问题:-)

更详细的,行:

node *temp;

temp 设置为指向某个“随机”位置,除非您的列表当前为空,否则在您尝试执行之前,不会更改

temp->next = newnode;

换句话说,它很可能会使用无效的指针值并崩溃 如果你幸运的话。如果你不幸, 它不会崩溃,但会在之后的某个时候表现出一些奇怪的行为。


如果您不担心列表中的 order,可以通过始终插入头部来解决这个问题,例如:

node *makenode(node *head, int val) {
    node *newnode = new node;
    newnode->data = val;
    if (head == 0) { // probably should use nullptr rather than 0.
        newnode->next = 0;
        newnode->prev = 0;
    } else {
        newnode->next = head->next;
        newnode->prev = 0;
    }
    head = newnode;
    return head;
}

如果您关心顺序,您必须根据值找出新节点应该去哪里,例如with:

node *makenode(node *head, int val) {
    node *newnode = new node;
    newnode->data = val;

    // Special case for empty list, just make new list.

    if (head == 0) { // probably should use nullptr rather than 0.
        newnode->next = 0;
        newnode->prev = 0;
        head = newnode;
        return head;
    }

    // Special case for insertion before head.

    if (head->data > val) {
        newnode->next = head->next;
        newnode->prev = 0;
        head = newnode;
        return head;
    }

    // Otherwise find node you can insert after, and act on it.

    // Checknode will end up as first node where next is greater than
    // or equal to insertion value, or the last node if it's greater
    // than all current items.

    node *checknode = head;
    while (checknode->next != 0 && (checknode->next->data < val) {
        checknode = checknode->next;
    }

    // Then it's just a matter of adjusting three or four pointers
    // to insert (three if inserting after current last element).

    newnode->next = checknode->next;
    newnode->prev = checknode;
    if (checknode->next != 0) {
        checknode->next->prev = newnode;
    }
    checknode->next = newnode;

    return head;
}

你们实际上并没有link在一起。此行:if(head==0) temp=head=newnode; 是您的 linked 列表包含值的唯一原因。第一个值将 head 设置为等于它,当您打印 head 时,您将获得该值。为了正确地做一个 linked 列表,你需要一个 headtail 指针。 head 指向列表中的第一个元素,tail 指向最后一个元素。当您将一个元素添加到列表的末尾时,您使用 tail 找到最后一个元素并向其添加 link 。把Linked List做成class最简单,可以封装head和tail:

struct Node {
public:
    int data;
    node *next;
    node *prev;
    Node(int data) : data(data), next(nullptr), prev(nullptr) {} // constructor
};

class LinkedList {
private:
    Node* head;
    Node* tail;

public:
    LinkedList() { head = tail = nullptr; }

    // This function adds a node to the end of the linked list
    void add(int data) {
        Node* newNode = new Node(data);
        if (head == nullptr) { // the list is empty
            head = newNode;
            tail = newNode;
        }
        else { // the list is not empty
            tail->next = newNode; // point the last element to the new node
            newNode->prev = tail;  // point the new element to the prev
            tail = tail->next;  // point the tail to the new node
        }
    }
};

int main() {

  LinkedList lList;
  lList.add(1);
  lList.add(2);
  // etc...

  return 0;
}