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



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

我不明白代码中的问题在哪里。

输入

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<<" VALUEn";
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设置为指向实际的节点而不是指向某个任意内存地址究竟是什么?

"Nothing";,我听到你说?好吧,那将是一个问题:-(

更详细地说,行:

node *temp;

将CCD_ 4设置为指向某个"0";"随机";位置,除非您的列表当前为空,否则在您尝试执行之前,不会有任何更改

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

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

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;是您的链表包含值的唯一原因。第一个值将打印头设置为等于它,当您打印打印头时,您将获得该值。为了正确执行链表,您需要一个指针。头部指向列表中的第一个元素,尾部指向最后一个元素。当你将一个元素添加到列表的末尾时,你可以使用tail找到最后一个元素并链接到它。最简单的方法是将Linked list作为一个可以封装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;
}

最新更新