提问者:小点点

为什么它只打印第一个值的双链表和比我的程序是崩溃


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

我无法理解代码中的问题出在哪里。

输入

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;

}

共2个答案

匿名用户

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;

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

如果您不担心列表中的顺序,可以通过总是在列表的头部插入来解决这个问题,例如:

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;
}

匿名用户

你实际上没有把任何东西联系在一起。 这一行:if(head==0)temp=head=newnode;是链表包含值的唯一原因。 第一个值将head设置为等于它,当您打印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
            tail = tail->next;  // point the tail to the new node
        }
    }
};

int main() {

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

  return 0;
}