我很难弄清楚为什么我的双重链接列表会崩溃,我可以找到一些方向



全面披露:这是我班的一个项目,但我不是来请你帮我做作业的。我正在寻找一个方向,看看我似乎缺少了什么。

分配:来自格式化数据文件(见下文)。您要创建3个双链接列表。(因此,一组数据有三个"链",以数字顺序排列数据)如果您遇到一段与前一段数据具有相同时间戳的数据,则该数据被认为是不可靠的,需要从双链接列表中删除。

问题:我有四个链表头,timeHead、tempHead和windHead用于从文件中读取的数据。最后一个是dupleHead(dupliteHead)用于列出重复项。我的问题是,每当我试图从链接列表中删除特定节点时。我似乎做得不对。要么程序崩溃,要么双链接列表崩溃。

这是我的代码:我觉得我的主要问题要么是没有正确创建列表,要么就是没有正确删除问题节点。

int主函数只调用两个函数addData和print report。我已经包括了我觉得相关的内容。

//ADD TO LINKED LIST
void linkedlist::addToLinkedList(weatherdata *newNode){
int doubleMarker = 0;
weatherdata *newNodeCopy;
weatherdata *currentNode;
weatherdata *nextNode;
newNodeCopy = new weatherdata;      //  <-- NEW
newNodeCopy = newNode;
/*_____ lINKED lIST FOR TIMESTAMP _____*/
//checks the duplicate list so as not to add a deleted triple
if (isItInDuplicateList(newNode) == 1){
doubleMarker = 1;
}
//if something exists in the list do this: traverse the list, check for duplicates.
if ((timeHead != nullptr) && (doubleMarker != 1)){  
currentNode = timeHead;
while (currentNode != nullptr){
//if its the same as another item DELETE
if (newNode->time == currentNode->time) {
addToDuplicateList(newNode);
deleteNodeFromList(newNode);
doubleMarker = 1;   //      <-- this double marker will ensure that the function doesnt add a duplicate item
break;
}
currentNode = currentNode->timeN;
}       
}
//if the incoming number is not a duplicate of something we already have on our list we add it
if (doubleMarker != 1){
//very first item on list
if (timeHead == nullptr){
timeHead = newNodeCopy;
}
//first position on list
else if (newNode->time < timeHead->time){
nextNode = timeHead;
timeHead = newNodeCopy;
newNodeCopy->timeN = nextNode;
nextNode->timeP = newNodeCopy;
}
//either between 2 entries or at the end of the list
else {
//traverse the list and find the appropriate placement for the newNode
currentNode = timeHead;
nextNode = timeHead->timeN;
//while "not yet at the end of the list"
while (nextNode != nullptr){
//newNode belongs somewhere in between two other entries
if ((currentNode->time < newNode->time) && (newNode->time < nextNode->time)){
currentNode->timeN = newNodeCopy;
newNodeCopy->timeP = currentNode;
newNodeCopy->timeN = nextNode;
nextNode->timeP = newNodeCopy;
break;
}
//otherwise increment currentNode and nextNode and compare again
else {
currentNode = nextNode;
nextNode = nextNode->timeN;
}
}
//newNode goes at the end of the linked List
if (nextNode == nullptr){
currentNode->timeN = newNodeCopy;
newNodeCopy->timeP = currentNode;
}
}
}
/*_____ lINKED lIST FOR TEMPERATURE _____*/
//if the incoming number is not a duplicate of something we already have on our list we add it
if (doubleMarker != 1){
//very first item on list
if (tempHead == nullptr){
tempHead = newNodeCopy;
}
//first position on list
else if (newNode->temp < tempHead->temp){
nextNode = tempHead;
tempHead = newNodeCopy;
newNodeCopy->tempN = nextNode;
nextNode->tempP = newNodeCopy;
}
//either between 2 entries or at the end of the list
else {
//traverse the list and find the appropriate placement for the newNode
currentNode = tempHead;
nextNode = tempHead->tempN;
//while "not yet at the end of the list"
while (nextNode != nullptr){
//newNode belongs somewhere in between two other entries
if ((currentNode->temp <= newNode->temp) && (newNode->temp <= nextNode->temp)){
currentNode->tempN = newNodeCopy;
newNodeCopy->tempN = nextNode;
nextNode->tempP = newNodeCopy;
break;
}
//otherwise increment currentNode and nextNode and compare again
else {
currentNode = nextNode;
nextNode = nextNode->tempN;
}
}
//newNode goes at the end of the linked List
if (nextNode == nullptr){
currentNode->tempN = newNodeCopy;
newNodeCopy->tempP = currentNode;
}
}
}
/*_____ lINKED lIST FOR WINDSPEED _____*/
//if the incoming number is not a duplicate of something we already have on our list we add it
if (doubleMarker != 1){
//very first item on list
if (windHead == nullptr){
windHead = newNodeCopy;
}
//first position on list
else if (newNode->wind < windHead->wind){
nextNode = windHead;
windHead = newNodeCopy;
newNodeCopy->windN = nextNode;
nextNode->windP = newNodeCopy;
}
//either between 2 entries or at the end of the list
else {
//traverse the list and find the appropriate placement for the newNode
currentNode = windHead;
nextNode = windHead->windN;
//while "not yet at the end of the list"
while (nextNode != nullptr){
//newNode belongs somewhere in between two other entries
if ((currentNode->wind <= newNode->wind) && (newNode->wind <= nextNode->wind)){
currentNode->windN = newNodeCopy;
newNodeCopy->windN = nextNode;
nextNode->windP = newNodeCopy;
break;
}
//otherwise increment currentNode and nextNode and compare again
else {
currentNode = nextNode;
nextNode = nextNode->windN;
}
}
//newNode goes at the end of the linked List
if (nextNode == nullptr){
currentNode->windN = newNodeCopy;
newNodeCopy->windP = currentNode;
}
}
}
}
//ADD TO DUPLICATE LIST
void linkedlist::addToDuplicateList(weatherdata *duplicateNode){
weatherdata *currentNode;
weatherdata *nextNode;
weatherdata *addDuplicateNode;
addDuplicateNode = new weatherdata;     //      <-- NEW
//make a complete copy for the duplicate list (since were going to delete that node)
addDuplicateNode->time = duplicateNode->time;
addDuplicateNode->temp = duplicateNode->temp;
addDuplicateNode->wind = duplicateNode->wind;   
addDuplicateNode->timeN = duplicateNode->timeN;
addDuplicateNode->timeP = duplicateNode->timeP;
addDuplicateNode->tempN = duplicateNode->tempN;
addDuplicateNode->tempP = duplicateNode->tempP;
addDuplicateNode->windN = duplicateNode->windN;
addDuplicateNode->windP = duplicateNode->windP;
addDuplicateNode->duplN = duplicateNode->duplN;
if (duplHead == nullptr){
duplHead = addDuplicateNode;
}
else {
currentNode = duplHead;
nextNode = duplHead->duplN;
while (nextNode != nullptr){
currentNode = nextNode;
nextNode = nextNode->duplN;
}   
currentNode->duplN = addDuplicateNode;
}
}

/DELETE FROM LINKEDLIST
void linkedlist::deleteNodeFromList(weatherdata *toBeDeletedNode){
weatherdata *currentNode;
weatherdata *nextNode;
currentNode = timeHead;
nextNode = timeHead->timeN; 
while (nextNode != nullptr){
if (nextNode->time == toBeDeletedNode->time){
currentNode->timeN = nextNode->timeN;
//currentNode->tempN = nextNode->tempN;
//cout << ".";
delete toBeDeletedNode;
toBeDeletedNode = nullptr;
break;
}
currentNode = nextNode;
nextNode = nextNode->timeN;
}
}
//DUPLICATE LIST CHECK
bool linkedlist::isItInDuplicateList(weatherdata *checkThisNode){
bool found = false;
weatherdata *currentNode;   
currentNode = duplHead;
if (duplHead == nullptr){
found = false;
}
else {
do {
if (currentNode->time == checkThisNode->time) {
found = true;
break;
}
currentNode = currentNode->duplN;
} while (currentNode != nullptr);
}
return found;   
}

因此,要么第一个(长)函数linkedlist addToLinkedList();或者最后一个(短)函数linkedlist deleteNodeFromList();

如果你需要我发布更多的代码,请告诉我,我会的。同样,我觉得我要么没有正确地制作双链接列表,要么没有正确删除它。

再次感谢!

首先看一下这些行:

newNodeCopy = new weatherdata;      //  <-- NEW
newNodeCopy = newNode;

在第一行中,创建一个类型为weatherdata的新对象,并在newNodeCopy中保存指向该新对象的指针。

在第二行中,您用newNode的值覆盖newNodeCopy的值,这意味着您丢失了指向新对象的指针(即内存泄漏)。

如果要将newNode指向的对象中的值复制到新创建的对象中,则需要执行以下操作:

*newNodeCopy = *newNode;

一般来说,我建议您将函数拆分为三个较小的函数(即每个列表一个)。较小的函数更易于理解和调试。

我还注意到这个部分:

if (isItInDuplicateList(newNode) == 1){
doubleMarker = 1;
}

在你所做的功能中的所有剩余代码中:

if (doubleMarker != 1){
.....
}

换句话说,一旦doubleMarker设置为1,就不会执行更多的代码。因此,您可以通过立即返回来简化代码。类似:

if (isItInDuplicateList(newNode) == 1){
return;
}

然后,您可以删除所有的if (doubleMarker != 1){,您的代码变得更易于阅读、理解和调试。

删除功能

你的void linkedlist::deleteNodeFromList(weatherdata *toBeDeletedNode)有一些严重的问题-考虑一下:

1) 如果timeHead是nullptr,会发生什么?

2) 如果timeHead->time == toBeDeletedNode->time,你在哪里检查?

3) 您在哪里更新timeP指针?

答案是:

1) 程序崩溃

2) Never-因此不能删除head元素。

3) 从来没有——所以你的清单被打破了!您需要添加更新"上一个"指针的代码

相关内容

最新更新