在双链表中最后追加或插入
appending or insertion at last in doubly linked list
我试图在双链表的末尾插入一个值,我成功地在头或第一个节点插入了值,但第二个值没有插入
这里的问题是在输入第二个值时
class d_list
{
private:
struct node
{
double data;
node *next;
node *previous;
};
node *first;
node *last ;
public:
d_list(void)
{
first = nullptr;
last = nullptr;
};
void append(double);
};
void d_list::append(double num)
{
node *ptr;
node *toinsert;
if(!first)
{
first = new node;
first->previous= nullptr;
first->data = num;
last= new node;
first->next= last->previous;
last->previous = first->next;
last->next= nullptr;
}
else
{
if(last->next == nullptr)
{
ptr = new node;
ptr->next =last->previous;
ptr->data=num;
last->previous = ptr->next ;
}
last->next= nullptr;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
d_list aa;
cout<<"going to append first"<<endl;
aa.append(44);
cout<<"going to append second"<<endl;
aa.append(50.5);
return 0;
}
您的代码中有许多问题:
node
的下一个和上一个成员从未在任何位置初始化,因此在使用时未定义。向node
添加构造函数,或者确保它们在分配后初始化- 将节点添加到空列表中是不正确的。
first->next
未定义,为什么要创建两个节点,第一个和最后一个?在一个有一个元素的列表中,然后是first == last
。在first/last中设置next/perior也没有任何意义 - 在格式良好的双链表中,
last->next
应该始终为null,first->previous
也应该为null - 将节点添加到非空列表中也是不正确的
- 虽然您没有在示例中显示它,但您最终需要一个析构函数以及一个复制运算符和复制构造函数(三者规则)。目前你正在泄漏内存,如果你试图删除节点,很可能会导致双倍空闲和崩溃
我建议从代码中退一步,以确保您正确理解双链表背后的概念。用下一个/上一个箭头在纸上画出一个列表,看看在向空/非空列表中添加节点时需要如何更改它们,以及如何删除和移动节点。一旦您弄清楚应该如何设置next/prev,那么将其转换为代码应该是相对直接的。
编辑以回答评论:要添加一个新节点,从技术上讲,你可以在任何地方添加它,但它通常是在最后添加的(至少从我看到的情况来看)。有关在空和非空列表中添加新节点的完整正确代码,请参阅其他答案。
...
if(last->next == nullptr)
{
ptr = new node;
ptr->next =last->previous; // <- is not correct
ptr->data=num;
last->previous = ptr->next ; // <- does not do anything useful
...
您不会将新节点附加到列表中。
...
if(!last->next)
{
ptr = new node;
ptr->previous=last->previous;
ptr->next =last;
ptr->data=num;
last->previous = ptr ;
...
应该更好。顺便说一句:删除析构函数中分配的内存!
我会用以下代码编写您的双链接列表:
#include <iostream>
using namespace std;
class d_list
{
private:
struct node
{
double data;
node *next;
node *previous;
};
node *first;
// node *last ; no need for bidirectional list
public:
d_list(void)
{
first = nullptr;
//last = nullptr;
};
void append(double);
};
void d_list::append(double num)
{
node *ptr = new node;
ptr->data = num;
node *toinsert;
if(!first)
{
first = ptr;
first->previous=first->next=first;
}
else
{
if(first->next == first)
{
ptr->next = ptr->previous = first;
first->next = first->previous = ptr;
}
else{
node *last = first->previous;
ptr->next = first;
ptr->previous = last;
last->next = ptr;
first->previous = ptr;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
d_list aa;
cout<<"going to append first"<<endl;
aa.append(44);
cout<<"going to append second"<<endl;
aa.append(50.5);
return 0;
}
如果不使用声明node *ptr;
和node *toinsert;
,为什么要插入它们?同样显而易见的是,如果在末尾插入一个节点,则只应创建一个新元素(如果第一个为null,则调用new两次)。
试试这个代码。。。
class d_list
{
private:
struct node
{
double data;
node *next;
node *previous;
};
node *first;
node *last ;
public:
d_list(void)
{
first = nullptr;
last = nullptr;
};
void append(double);
};
void d_list::append(double num)
{
node *ptr;
node *toinsert;
if(!first)
{
first = last = new node;
first->previous= nullptr;
first->next = nullptr;
first->data = num;
}
else
{
ptr = new node;
ptr->next =last->previous;
ptr->data=num;
last->previous = ptr->next ;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
d_list aa;
cout<<"going to append first"<<endl;
aa.append(44);
cout<<"going to append second"<<endl;
aa.append(50.5);
return 0;
}
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 预处理器:插入结构名称中的前一个行号
- 在未初始化映射的情况下,将值插入到映射的映射中
- 如何在c++中只将键插入到bimap的一侧
- 如何将结构插入到集合中并打印集合的成员
- C++json插入数组
- Visual Studio 2019:插入多个C++风格的单行注释
- nlohmann-json将一个数组插入到另一个数组中
- 有效地使用std::unordered_map来插入或增加键的值
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 正在插入动态数组
- 插入或删除时获取usb的dos_name
- 叮叮当当在修复时插入多个"覆盖"说明符
- 链表c++插入,所有情况都已检查,但没有任何工作
- C++ 在追加 Windows API 的特定位置插入文本
- 追加/打印/插入数组c++函数问题
- 在双链表中最后追加或插入
- 有效地向字符串追加或插入可变数量的空格
- 无法在c++中使用追加模式在文件中插入数据