难以弄清楚为什么我的双重链表正在崩溃,我可以使用某个方向

时间:2017-02-12 11:06:50

标签: c++ linked-list

完全披露:这是我班上的一个项目,但我不是要求你为我做功课。我正在寻找一个关于我似乎缺少什么的方向。

作业:来自格式化数据的文件(见下文)。您将创建3个双向链表。 (所以一组数据有三个“链”,用数字命令数据)如果你遇到的数据与前一段数据的时间戳相同,那么这些数据被认为是不可靠的,需要从中删除双重链表。

问题:我有四个链表头,timeHead,tempHead和windHead用于从文件中读取数据。最后一个是duplHead(duplicateHead)用于重复列表。我的问题是每当我尝试从链表中删除特定节点时。我似乎无法正确地做到这一点。我要么崩溃程序,要么双重链表崩溃。

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

int main函数只调用两个函数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();

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

再次感谢!

1 个答案:

答案 0 :(得分:1)

首先看一下这几行:

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

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

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

如果要将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)从不 - 所以你不能删除头元素。

3)从不 - 所以你的名单坏了!您需要添加更新“上一个”指针的代码