C++ 在末尾插入双链接列表节点
我正在尝试创建一个函数,用于在双链接列表的末尾添加。我无法精确指出为什么它没有打印出任何内容 当我构建程序时,没有出现错误 我确信 1.新建节点首先检查头部是否有任何值C++ 在末尾插入双链接列表节点,c++,C++,我正在尝试创建一个函数,用于在双链接列表的末尾添加。我无法精确指出为什么它没有打印出任何内容 当我构建程序时,没有出现错误 我确信 1.新建节点首先检查头部是否有任何值 在上一个当前指针之后创建 我将前一个节点连接到新节点,新节点指向前一个节点,而新节点指向nullptr作为下一个节点 #包括“pch.h” #包括 使用名称空间std; 班级名单; 类节点{ 公众: int数据; 节点*下一步; 节点*prev; 好友类列表; }; 类列表{//双列表 节点*头; 节点*尾部; 公众: list
#包括“pch.h”
#包括
使用名称空间std;
班级名单;
类节点{
公众:
int数据;
节点*下一步;
节点*prev;
好友类列表;
};
类列表{//双列表
节点*头;
节点*尾部;
公众:
list(){head=nullptr;tail=nullptr;head->next=tail;tail->prev=head;}
节点*回推(int newdata){
节点*curr=新节点;
当前->数据=新数据;
curr->next=nullptr;
if(head==nullptr){
水头=电流;
回流头;
}
节点*precurr=头部;
while(预curr->next!=nullptr){
预curr=预curr->next;
}
预curr->next=当前;
当前->当前=预当前;
回流头;
}
作废打印(){
while(head->next!=nullptr){
cout data您已经做了很多正确的事情,但是您对构造函数以及对->prev
和tail
指针的使用感到困惑
如注释中所述,您的构造函数的直接问题是您将head
和tail
设置为nullptr
,然后立即取消head
和tail
的引用,试图进行head
和tail
自引用(仅在循环链接列表中需要)
通过将head
和tail
设置为nullptr
,您没有一个指向有效节点的指针,因此无法取消引用。您尝试设置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;
(注意:atail
指针是可选的,循环列表为head->prev
始终指向列表中的最后一个节点)
由于您的问题属于双链接列表而不是循环列表,因此您只需将头
和尾
设置为等于新节点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=curr;
,更新指向新结束节点的tail
指针
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');
}
示例使用/输出
$ ./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
检查一下,如果您还有其他问题,请告诉我。您列表
构造函数有UB。您正在将head
设置为nullptr
,然后立即使用head->next
。当我运行您的代码时,我遇到了一个分段错误(这比不打印列表的内容更令人担忧)。当我修复分段错误(UB)时,代码可以工作。它不太好,因为它忽略了tail
,但它确实打印了列表。
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');
}
#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