这是我的 C++ 代码:
#include <iostream>
using namespace std;
typedef struct Node
{
int data;
Node* next;
}Node;
class LinkedList
{
private:
Node* first;
Node* last;
public:
LinkedList() {first = last = NULL;};
LinkedList(int A[], int num);
~LinkedList();
void Display();
void Merge(LinkedList& b);
};
// Create Linked List using Array
LinkedList::LinkedList(int A[], int n)
{
Node* t = new Node;
if (t == NULL)
{
cout << "Failed allocating memory!" << endl;
exit(1);
}
t->data = A[0];
t->next = NULL;
first = last = t;
for (int i = 1; i < n; i++)
{
t = new Node;
if (t == NULL)
{
cout << "Failed allocating memory!" << endl;
exit(1);
}
t->data = A[i];
t->next = NULL;
last->next = t;
last = t;
}
}
// Deleting all Node in Linked List
LinkedList::~LinkedList()
{
Node* p = first;
Node* tmp;
while (p != NULL)
{
tmp = p;
p = p->next;
delete tmp;
}
}
// Displaying Linked List
void LinkedList::Display()
{
Node* tmp;
for (tmp = first; tmp != NULL; tmp = tmp->next)
cout << tmp->data << " ";
cout << endl;
}
// Merge two linked list
void LinkedList::Merge(LinkedList& b)
{
// Store first pointer of Second Linked List
Node* second = b.first;
Node* third = NULL, *tmp = NULL;
// We find first Node outside loop, smaller number, so Third pointer will store the first Node
// Then, we can only use tmp pointer for repeating process inside While loop
if (first->data < second->data)
{
third = tmp = first;
first = first->next;
tmp->next = NULL;
}
else
{
third = tmp = second;
second = second->next;
tmp->next = NULL;
}
// Use while loop for repeating process until First or Second hit NULL
while (first != NULL && second != NULL)
{
// If first Node data is smaller than second Node data
if (first->data < second->data)
{
tmp->next = first;
tmp = first;
first = first->next;
tmp->next = NULL;
}
// If first Node data is greater than second Node data
else
{
tmp->next = second;
tmp = second;
second = second->next;
tmp->next = NULL;
}
}
// Handle remaining Node that hasn't pointed by Last after while loop
if (first != NULL)
tmp->next = first;
else
tmp->next = second;
// Change first to what Third pointing at, which is First Node
first = third;
// Change last pointer from old first linked list to new last Node, after Merge
Node* p = first;
while (p->next != NULL)
{
p = p->next;
}
last = p;
// Destroy second linked list because every Node it's now connect with first linked list
// This also prevent from Double free()
b.last = NULL;
b.first = NULL;
}
int main()
{
int arr1[] = {4, 8, 12, 14, 15, 20, 26, 28, 30};
int arr2[] = {2, 6, 10, 16, 18, 22, 24};
int size1 = sizeof(arr1) / sizeof(arr1[0]);
int size2 = sizeof(arr2) / sizeof(arr2[0]);
LinkedList l1(arr1, size1);
LinkedList l2(arr2, size2);
l1.Display();
l2.Display();
// Merge two linked list, pass l2 as reference
l1.Merge(l2);
l1.Display();
return 0;
}
我是 C++ 的初学者,在这段代码中,我练习如何合并两个链表。这实际上非常有效。我已经按排序顺序成功合并了两个链接列表。
但是,有人说我应该遵循C++的三法则。其中实现:Destructor,Copy Constructor和Copy Assignment Operator。
我看过很多关于那个的视频。我确实理解这基本上是处理浅拷贝,特别是当我们不希望两个不同的对象指向相同的内存地址时。但是,对于我的问题是,我仍然不知道如何在链接列表上工作的类上实现它,就像我上面的代码一样。
有人说,在我的 中main()
,这段代码:l1.Merge(l2);
不知何故不正确,因为我没有明确的复制构造函数。
如果你看我的Merge()
函数,在最后一行,如果我没有这样做:b.last = NULL;
和b.first = NULL;
,它只会破坏第二个链接列表的指针,编译器会给我警告:检测到双释放()。
所以,我想我的问题是:
- 这段代码怎么会:
l1.Merge(l2);
与复制构造函数有关? - 是
Double free()
因为我没有执行三法则吗?如果是,如何解决? - 如何根据我的代码编写三法则?何时或如何使用它们?
- 根据本准则,有什么问题吗?如果我的程序只想合并链表,我还需要三法则吗?
谢谢你。我希望有人能像我10岁一样向我解释。并希望有人可以给我写一些代码。