实现链表
Implementing a Linked List
我正在C++中实现链表。虽然我过去在java中做过这件事,但我不知道如何在C++中用指针来做,因为代码正在编译,但当我运行它时,它会给我一个分段错误。我做错了什么?
我的节点.h文件
#ifndef NODE_H
#define NODE_H
#include <string>
using namespace std;
class Node
{
public:
Node(const string, const int) ;
~Node() { }
void setNext(Node *); // setter for the next variable
Node * getNext(); // getter for the next variable
string getKey(); // getter for the key variable
int getDistance(); // getter for the dist variable
private:
Node *next;
int dist;
string key;
};
#endif
我的Node.cpp文件
#include "node.h"
#include <string>
Node::Node(string key, int dist){
key = key;
dist = dist;
}
void Node::setNext(Node * next){
next->next;
}
Node * Node::getNext(){
return this->next;
}
string Node::getKey(){
return key;
}
int Node::getDistance(){
return dist;
}
和我的main.cpp文件
#include "node.h"
#include <iostream>
using namespace std;
int main(){
Node* nptr1 = new Node("Test1", 2);
Node* nptr2 = new Node("Test2", 2);
Node* temp;
nptr1->setNext(nptr2);
temp = nptr1->getNext();
cout << temp->getKey() << "-" << temp->getDistance() << endl;
}
如有任何帮助,我们将不胜感激。谢谢
您应该将所有成员初始化为定义的值。您不应该对参数和成员进行相同的命名,这几乎总是会导致混淆,或者更可能导致错误
Node::Node(string key_val, int distance)
: next(0)
{
key = key_val;
dist = distance;
}
更好的是,使用成员初始化
Node::Node(string key_val, int distance)
: next(0),
key(key_val),
dist(distance)
{
}
正如评论者已经指出的那样,必须将setNext()
中的next
指针设置为给定的参数,并且应该而不是修改参数,而是this->next
成员
void Node::setNext(Node * next_ptr){
next = next_ptr;
}
在具有指针/动态内存分配的语言中,链表和其他数据结构的关键是为每个操作映射出所有可能的状态(情况)。您必须确保您的代码正确地处理每种情况下的指针和内存。这可能就是为什么你被要求实现它的原因:教你如何思考出现的陷阱。因此,我不会简单地给你一个直接的解决方案,而是概述你如何抓住这个机会来理解基本概念,这些概念将在未来帮助你和其他人解决这个问题。
即使是在一个带有尾部插入的stage1(非常基本的)链表中,也应该开发某种映射方案。我个人的经验是,对于main()
:中的每一行
- 为每个对象绘制一个方框
- 在框中列出所有数据变量
- 在非指针变量旁边列出任何初始化/赋值
- 从指针变量到您知道正在指向的对象绘制箭头
- 将箭头从指针变量绘制到未分配指针的空白区域
需要知道的一件事是,未初始化的数据和指针显示出未定义的属性,这些属性因操作系统/编译器而异,因此,用合适的初始值定义它们中的大多数通常是至关重要的。我发现,在声明时始终初始化为安全默认值对我很有帮助(在某些情况下,这是不可能的或会产生性能问题,但这些问题可以根据需要进行处理,例如懒惰初始化)。与Java不同,基本C++默认情况下不会引发空指针异常、提供初始值或垃圾收集(它高度依赖于编译器/库和传递的选项)。在最好的情况下,你的程序会出错(一个更普遍的例外,通常意味着你已经访问了不应该访问的内存),在更糟糕的情况下它要么仍然工作,但行为不可预测,要么在没有反馈的情况下崩溃。因此,您应该使用映射方案来验证是否没有对指向NULL
的指针或指向已执行free
/delete
的对象的指针执行操作。此外,您还需要确保它们指向的位置是有意义的。与任何链接方案一样,您可能会遇到悖论,如将节点链接到自身或创建循环链接。
因此,如前所述,跟踪每次手术的所有可能病例也很重要。如果这个程序是一种学习数据结构或指针的方法,正如我所怀疑的那样,那么毫无疑问,您将被要求实现更高级的列表。更高级的列表可能很棘手,所以你应该尽早养成习惯,尝试确定执行特定操作可能需要格外小心(角落案例)。对于列表,您应该考虑列表为空、有1个元素、有2个元素或有2个以上元素的情况。您可能还需要考虑是否从开始、结束或两者之间的某个位置插入/删除元素。再次,广泛使用映射来了解这些情况将如何发展。你真的应该试着用前面提到的方法来思考这个问题,但你也可以查看维基百科或数据结构教科书来了解更多信息。
顺便说一句,正如Raymond提到的,你可以使用调试器来帮助你发现问题。事实上,如果您以前没有使用过C/C++调试器,那么现在正是学习的最佳时机。完成这项工作后,请查阅针对您的平台的C/C++调试器上的文档。尝试使用它逐步遍历非工作代码的main()
,并查看数据值是否与映射中的期望值匹配。这种技能将在以后被证明是非常宝贵的
此外,请注意,this
通常是C++中的指针,因此不要将其与Java/Python中的使用方式混淆:正如一些人所建议的,使用this->somedata
notthis.somedata
访问成员数据。话虽如此,为了更清楚起见,您可能希望在参数名称与成员变量相同的地方使用this->somedata = somedata
的约定。当然,使用不同参数名称的建议也同样有效。
- 如果没有malloc,链表实现将失败
- 不了解链表实现,请帮忙.C++
- 使用链表实现堆栈时出错
- 如何编写一个类似于kernellist_head的c++风格的双链表实现
- C++中链表实现的问题
- 链表实现 c++
- 难以理解链表实现(结构部分)?
- 为什么下面的使用链表实现线性队列的代码返回垃圾值然后崩溃
- 如何将自己的链表实现从存储整数更改为存储个人数据
- 在我的C++链表实现中取消引用节点指针,给出意想不到的结果
- C++ 中堆栈的链表实现
- c++ 中 if 语句中的多个条件(通过链表实现堆栈)
- C++ 访问数据的链表实现
- 使用链表实现队列
- 此链表实现中的错误
- 试图用c++编写我自己的链表实现,在点击列表中的3个元素后编写segfault代码
- 通过数组实现BST,通过链表实现堆
- 从后到前显示使用链表实现的队列
- C++链表实现多数据插入
- 反转使用链表实现的堆栈