我正在尝试创建一个函数,以便在最后添加双链表。我无法查明为什么它不打印任何内容。
构建程序时没有出现错误。
我确定1.新节点首先检查头部是否具有任何值
在前一个当前指针之后创建的指针
我将上一个节点连接到新节点,新节点指向上一个节点,而新节点则指向下一个nullptr。
#include "pch.h"
#include <iostream>
using namespace std;
class list;
class node {
public:
int data;
node *next;
node *prev;
friend class list;
};
class list {//double list
node* head;
node* tail;
public:
list(){ head = nullptr; tail = nullptr; head->next = tail; tail->prev = head;}
node* pushback(int newdata) {
node* curr = new node;
curr->data = newdata;
curr->next = nullptr;
if (head == nullptr) {
head = curr;
return head;
}
node*precurr = head;
while (precurr->next != nullptr){
precurr = precurr->next;
}
precurr->next = curr;
curr->prev = precurr;
return head;
}
void print() {
while (head->next != nullptr) {
cout << head->data << " " << endl;
head = head->next;
}
}
};
int main()
{
list test;
test.pushback(1);
test.pushback(2);
test.pushback(3);
test.pushback(4);
test.pushback(5);
test.pushback(6);
test.print();
return 0;
}
您已经正确完成了很多事情,但是您对构造函数以及对->prev
和tail
指针的使用感到困惑。
如注释中所述,您的构造函数立即出现问题,是您将head
和tail
设置为nullptr
,然后立即取消引用head
和tail
尝试使head
和tail
]自引用(仅在circularlinked-list中需要)。
list(){ head = nullptr; tail = nullptr; head->next = tail; tail->prev = head;}
将head
和tail
设置为nullptr
,您没有指向有效node
的指针,无法对其进行取消引用。您尝试设置head->next = tail; tail->prev = head;
的操作立即失败,导致出现SegFault。
出于在普通非圆形列表中的目的,您只需在构造函数中省略设置head->next
和tail->prev
,例如
list() { head = nullptr; tail = nullptr; }
如果要使列表成为循环列表,则将head
和tail
自引用为:
node *pushback (int newdata) {
...
if (head == nullptr) /* for circular-list 1st node initialization */
head = tail = head->prev = head->next = tail->prev = tail->next = curr;
((note: tail
指针对于circular列表是可选的,因为head->prev
始终指向列表中的最后一个节点)
由于您的问题属于双链表而不是循环列表,因此您只需要将head
和tail
都设置为等于新节点curr
第一个节点的添加,例如
node *pushback (int newdata) {
node *curr = new node;
curr->data = newdata;
curr->next = curr->prev = nullptr;
if (head == nullptr)
head = tail = curr;
对于所有其他节点,不需要迭代(这是tail
指针的目的),只需将curr->prev
设置为tail
,将tail->next
设置为curr
,然后更新tail
指针通过设置tail = curr;
到新的终端节点,例如
else {
curr->prev = tail;
tail->next = curr;
tail = curr;
}
return head;
}
double-linked-list的目的是允许您在节点上进行正向和反向迭代。例如:
void printfwd() {
node *iter = head;
while (iter != nullptr) {
std::cout << ' ' << iter->data;
iter = iter->next;
}
std::cout.put('\n');
}
void printrev() {
node *iter = tail;
while (iter != nullptr) {
std::cout << ' ' << iter->data;
iter = iter->prev;
}
std::cout.put('\n');
}
(对于循环列表,迭代方案略有不同,因为您可以从任何节点进行正向和反向迭代,而无需从head
或tail
开始。要插入循环列表,只需简单地插入一个新的tail
节点)。
不要养成不良习惯。 Why is “using namespace std;” considered bad practice?当前您需要处理的只是cout
和endl
,继续删除using namespace std;
,只需在cout
和endl
前面加上std::
。
完全将其放入:
#include <iostream>
class list;
class node {
public:
int data;
node *next;
node *prev;
friend class list;
};
class list {//double list
node *head;
node *tail;
public:
list() { head = nullptr; tail = nullptr; }
node *pushback (int newdata) {
node *curr = new node;
curr->data = newdata;
curr->next = curr->prev = nullptr;
if (head == nullptr)
head = tail = curr;
else {
curr->prev = tail;
tail->next = curr;
tail = curr;
}
return head;
}
void printfwd() {
node *iter = head;
while (iter != nullptr) {
std::cout << ' ' << iter->data;
iter = iter->next;
}
std::cout.put('\n');
}
void printrev() {
node *iter = tail;
while (iter != nullptr) {
std::cout << ' ' << iter->data;
iter = iter->prev;
}
std::cout.put('\n');
}
};
int main() {
list test;
for (int i = 1; i <= 10; i++)
test.pushback(i);
std::cout << "\nforward:\n";
test.printfwd();
std::cout << "\nreverse:\n";
test.printrev();
}
示例使用/输出
$ ./bin/ll_double_int
forward:
1 2 3 4 5 6 7 8 9 10
reverse:
10 9 8 7 6 5 4 3 2 1
仔细检查,如果还有其他问题,请告诉我。