【发布时间】:2020-01-31 21:30:04
【问题描述】:
老实说,我已经在这工作了大约 10 个小时,尝试了一种又一种方法来让它发挥作用。我正在尝试创建一个第三个列表,它将 2 个列表合并在一起并从低到高排序(没有重复),然后将第一个列表设置为新列表,从而将第二个列表合并到第一个列表中。但是每当我运行程序时,我都会得到 listData == NULL,即使在 newListCurr 绝对应该向 newList 添加元素的测试用例中也是如此。我一直对链表有困难,所以也许我误解了一些基本原理,但我一生都无法弄清楚这一点。该方法不需要声明单个新节点,并且只能具有 O(n) 的时间复杂度,这使得这变得更加困难。我尝试了几种方法,例如尝试将它们直接插入 listData(第一个列表),但存在一个一致的问题,即 curr 指针实际上并未影响它们各自的 listData。
编辑:假定列表在合并之前排序。
这是合并方法,其他一切都按预期工作,只是合并方法搞砸了。
template <class ItemType>
void SortedList<ItemType>::merge(SortedList& list) {
Node<ItemType> * curr1 = listData;
Node<ItemType> * curr2 = list.listData;
Node<ItemType> * newList = NULL;
Node<ItemType> * newListCurr = newList;
while(curr2 != NULL || curr1 != NULL) {
if(curr2 == NULL) {
newListCurr = curr1;
curr1 = curr1->next;
newListCurr = newListCurr->next;
}
else if(curr1 == NULL) {
newListCurr = curr2;
curr2 = curr2->next;
newListCurr = newListCurr->next;
}
else if(curr1->info < curr2->info) {
newListCurr = curr1;
curr1 = curr1->next;
newListCurr = newListCurr->next;
} else if (curr2->info < curr1->info) {
newListCurr = curr2;
curr2 = curr2->next;
newListCurr = newListCurr->next;
}
else if (curr1->info == curr2->info) {
newListCurr = curr1;
curr1 = curr1->next;
curr2 = curr2->next;
newListCurr = newListCurr->next;
}
}
list.listData = NULL;
listData = newList;
}
编辑:我为可能遇到同样问题的人找到了解决方案。在使用 newListCurr 修改 newList 的其余部分之前,我需要将 newList 和 newListCurr 设置为一个节点。这是我更新的代码:
template <class ItemType>
void SortedList<ItemType>::merge(SortedList& list) {
Node<ItemType> * curr1 = listData;
Node<ItemType> * curr2 = list.listData;
Node<ItemType> * newList = NULL;
Node<ItemType> * newListCurr = newList;
if(curr2 != NULL || curr1!= NULL) {
if(curr2 == NULL) {
newListCurr = curr1;
curr1 = curr1->next;
} else if(curr1 == NULL) {
newListCurr = curr2;
curr2 = curr2->next;
} else if(curr1->info < curr2->info) {
newListCurr = curr1;
curr1 = curr1->next;
} else if (curr2->info < curr1->info) {
newListCurr = curr2;
curr2 = curr2->next;
} else if (curr1->info == curr2->info) {
newListCurr = curr1;
curr1 = curr1->next;
curr2 = curr2->next;
}
newList = newListCurr;
}
while(curr2 != NULL || curr1 != NULL) {
if(curr2 == NULL) {
newListCurr->next = curr1;
curr1 = curr1->next;
newListCurr = newListCurr->next;
}
else if(curr1 == NULL) {
newListCurr->next = curr2;
curr2 = curr2->next;
newListCurr = newListCurr->next;
}
else if(curr1->info < curr2->info) {
newListCurr->next = curr1;
curr1 = curr1->next;
newListCurr = newListCurr->next;
} else if (curr2->info < curr1->info) {
newListCurr->next = curr2;
curr2 = curr2->next;
newListCurr = newListCurr->next;
}
else if (curr1->info == curr2->info) {
newListCurr->next = curr1;
curr1 = curr1->next;
curr2 = curr2->next;
newListCurr = newListCurr->next;
}
}
list.listData = NULL;
listData = newList;
}
【问题讨论】:
-
我看到
Node<ItemType> * newList = NULL;,没有任何改变,然后是listData = newList;。为什么你认为newList不是NULL? -
通常想回答问题的人会从问题中获取代码,将其粘贴到文本文件中,编译并运行它以查看自己的错误所在。他们通常会使用各种尺寸、形状和用途的调试工具。让这件事尽可能简单符合提问者的最大利益。独立代码的片段使这变得困难。没有要运行的程序,并且在制作程序的过程中可能会意外修复错误或插入新错误。代码中的行号使这很难。在编译代码之前需要删除它们。
-
要遍历您的列表,您需要一个指向指针的指针,而不仅仅是一个指针。或者创建一个递归函数并使用对指针的引用。另一件事,你没有提到你的旧两个列表是否已订购。
-
@Kevin 是的,但我将 newListCurr 设置为 newList,然后使用 newListCurr 添加节点。 newList 只是作为对第三个列表头部的引用而存在。除非我做错了。您如何建议添加到 newList 同时保持对其第一个节点的引用?
-
几乎所有问题都可以归结为
main和一些支持功能。强烈建议在此处提出问题之前隔离错误,因为通常情况下,隔离错误可以让您在不提出问题的情况下识别和修复它。创建一个main,它建立两个排序列表,尝试合并它们,并产生错误的结果。如果这样做没有向您揭示解决方案,请询问有关此简单程序的问题。使用minimal reproducible example 获取灵感。
标签: c++ merge linked-list singly-linked-list