基本链表使用Constructor v/s静态方法
Using Constructor v/s static method for basic linked list
我在第一次尝试中尝试实现一个基本的链表我实现了一个静态方法(插入)来插入数据和指向下一个元素的指针,如下所示:
#include <iostream>
using namespace std;
class Node{
public:
int data = NULL;
Node* next = nullptr;
Node(){}
static void insert(int data, Node* next,Node* obj){
obj->data = data;
obj->next = next;
}
static void printList(Node* n){
while(n != nullptr){
cout << n->data << " ";
n = n->next;
}
}
};
int main()
{
Node* head = nullptr;
Node* second = nullptr;
Node* third = nullptr;
head = new Node();
second = new Node();
third = new Node();
//via static method
Node::insert(1,second,head);
Node::insert(2,third,second);
Node::insert(3,nullptr,third);
Node::printList(head);
delete head;
delete second;
delete third;
return 0;
}
如我所料,它工作正常(输出为 1 2 3),但是当我使用
构造函数如下所示:
#include <iostream>
using namespace std;
class Node{
public:
int data = NULL;
Node* next = nullptr;
Node(){}
Node(int data, Node* next){
this->data = data;
this->next = next;
}
static void printList(Node* n){
while(n != nullptr){
cout << n->data << " ";
n = n->next;
}
}
};
int main()
{
Node* head = nullptr;
Node* second = nullptr;
Node* third = nullptr;
//via constructors.
head = new Node(1,second);
second = new Node(2,third);
third = new Node(3,nullptr);
Node::printList(head);
delete head;
delete second;
delete third;
return 0;
}
我得到的输出为 1 0。当我从第三个到头调用构造函数时,它工作正常(我的意思是)
third = new Node(3,nullptr);
second = new Node(2,third);
head = new Node(1,second);
请解释为什么会这样。
注:我是编程初学者
让我们内联 insert
:
Node::insert(x, a, b)
等同于
b->data = x;
b->next = a;
因此,
Node::insert(1,second,head);
Node::insert(2,third,second);
Node::insert(3,nullptr,third);
等同于
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = nullptr;
现在 head->next
指向与 second
相同的节点,second->next
与 third
指向相同的节点 - 你也可以写
head->next = second;
head->data = 1;
head->next->next = third;
head->next->data = 2;
head->next->next->next = nullptr;
head->next->next->data = 3;
在失败的情况下,second
不会一直指向您链接到 first
的节点;它指向一个新节点。
由于您为 second
和 third
分配了新值,因此它等同于
head = new Node(1,second);
Node* fourth = new Node(2,third);
Node* fifth = new Node(3,nullptr);
现在您很快就会明白为什么它不起作用。
您也可以绘制“框和指针”图。
(初学者很不愿意做,别这样,比调试快多了。)
让我们看看失败的原因:
head = new Node(1, second);
head second
| |
v v
+---+ +---+
| -------->| X |
+---+ +---+
然后
second = new Node(2,third);
head second third
| | |
v v v
+---+ +---+ +---+ +---+
| -------->| X | | -------->| X |
+---+ +---+ +---+ +---+
现在 head->next
指向的节点不同于 second
指向的节点 - 它仍然指向您首先创建的 default-initialized Node
。
虽然部分工作看起来像:
second = new Node(2, third);
second third
| |
v v
+---+ +---+
| -------->| X |
+---+ +---+
first = new Node(1,second);
head second third
| | |
v v v
+---+ +---+ +---+
| -------->| -------->| X |
+---+ +---+ +---+
现在,如果您不以“尽可能小的步骤”方式执行此操作,则可以编写您的工作构造函数代码
Node* third = new Node(3,nullptr);
Node* second = new Node(2,third);
Node* head = new Node(1,second);
但是坏掉的你这样写是编译不通过的,不编译也能发现有依赖问题:
Node* head = new Node(1,second); // second is undeclared
Node* second = new Node(2,third); // third is undeclared
Node* third = new Node(3,nullptr);
这是适应迈出更大步伐的另一个原因。
我在第一次尝试中尝试实现一个基本的链表我实现了一个静态方法(插入)来插入数据和指向下一个元素的指针,如下所示:
#include <iostream>
using namespace std;
class Node{
public:
int data = NULL;
Node* next = nullptr;
Node(){}
static void insert(int data, Node* next,Node* obj){
obj->data = data;
obj->next = next;
}
static void printList(Node* n){
while(n != nullptr){
cout << n->data << " ";
n = n->next;
}
}
};
int main()
{
Node* head = nullptr;
Node* second = nullptr;
Node* third = nullptr;
head = new Node();
second = new Node();
third = new Node();
//via static method
Node::insert(1,second,head);
Node::insert(2,third,second);
Node::insert(3,nullptr,third);
Node::printList(head);
delete head;
delete second;
delete third;
return 0;
}
如我所料,它工作正常(输出为 1 2 3),但是当我使用 构造函数如下所示:
#include <iostream>
using namespace std;
class Node{
public:
int data = NULL;
Node* next = nullptr;
Node(){}
Node(int data, Node* next){
this->data = data;
this->next = next;
}
static void printList(Node* n){
while(n != nullptr){
cout << n->data << " ";
n = n->next;
}
}
};
int main()
{
Node* head = nullptr;
Node* second = nullptr;
Node* third = nullptr;
//via constructors.
head = new Node(1,second);
second = new Node(2,third);
third = new Node(3,nullptr);
Node::printList(head);
delete head;
delete second;
delete third;
return 0;
}
我得到的输出为 1 0。当我从第三个到头调用构造函数时,它工作正常(我的意思是)
third = new Node(3,nullptr);
second = new Node(2,third);
head = new Node(1,second);
请解释为什么会这样。 注:我是编程初学者
让我们内联 insert
:
Node::insert(x, a, b)
等同于
b->data = x;
b->next = a;
因此,
Node::insert(1,second,head);
Node::insert(2,third,second);
Node::insert(3,nullptr,third);
等同于
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = nullptr;
现在 head->next
指向与 second
相同的节点,second->next
与 third
指向相同的节点 - 你也可以写
head->next = second;
head->data = 1;
head->next->next = third;
head->next->data = 2;
head->next->next->next = nullptr;
head->next->next->data = 3;
在失败的情况下,second
不会一直指向您链接到 first
的节点;它指向一个新节点。
由于您为 second
和 third
分配了新值,因此它等同于
head = new Node(1,second);
Node* fourth = new Node(2,third);
Node* fifth = new Node(3,nullptr);
现在您很快就会明白为什么它不起作用。
您也可以绘制“框和指针”图。
(初学者很不愿意做,别这样,比调试快多了。)
让我们看看失败的原因:
head = new Node(1, second);
head second
| |
v v
+---+ +---+
| -------->| X |
+---+ +---+
然后
second = new Node(2,third);
head second third
| | |
v v v
+---+ +---+ +---+ +---+
| -------->| X | | -------->| X |
+---+ +---+ +---+ +---+
现在 head->next
指向的节点不同于 second
指向的节点 - 它仍然指向您首先创建的 default-initialized Node
。
虽然部分工作看起来像:
second = new Node(2, third);
second third
| |
v v
+---+ +---+
| -------->| X |
+---+ +---+
first = new Node(1,second);
head second third
| | |
v v v
+---+ +---+ +---+
| -------->| -------->| X |
+---+ +---+ +---+
现在,如果您不以“尽可能小的步骤”方式执行此操作,则可以编写您的工作构造函数代码
Node* third = new Node(3,nullptr);
Node* second = new Node(2,third);
Node* head = new Node(1,second);
但是坏掉的你这样写是编译不通过的,不编译也能发现有依赖问题:
Node* head = new Node(1,second); // second is undeclared
Node* second = new Node(2,third); // third is undeclared
Node* third = new Node(3,nullptr);
这是适应迈出更大步伐的另一个原因。