2017-02-12 18 views
0

完全披露:這是我的課程,但我不是在這裏要求你爲我做作業。我正在尋找一個小小的方向,看看我似乎錯過了什麼。搞砸了爲什麼我的雙向鏈表崩潰了,我可以使用一些方向

賦值:從格式化數據文件(見下文)。您將創建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();

如果您需要我發佈任何代碼,請讓我知道,我會這麼做。 再次,我覺得我要麼沒有正確創建雙向鏈表,要麼沒有正確刪除它。

再次感謝!

+2

解決此類問題的正確工具是您的調試器。在*堆棧溢出問題之前,您應該逐行執行您的代碼。如需更多幫助,請閱讀[如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您應該\編輯您的問題,以包含一個[最小,完整和可驗證](http://stackoverflow.com/help/mcve)示例,該示例再現了您的問題,以及您在調試器。 –

+1

你有很長的功能和大量的重複代碼。您應該嘗試將其分解爲簡單函數(可能最多爲40行),並嘗試首先避免代碼重複。這將幫助您進行調試。 – felix

回答

1

首先來看看這些行:

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)有一些嚴重的問題 - 這樣考慮:如果

timeHead nullptr

1)會發生什麼?

2)你在哪裏檢查是否timeHead->time == toBeDeletedNode->time

3)你在哪裏更新timeP指針?

的答案是:

1)程序永不死機

2) - 所以你不能刪除頭元素。

3)永不 - 所以你的清單被打破了!您需要添加更新「上一個」指針的代碼

+0

感謝您抽出寶貴時間,我真的很感激。我會看看並嘗試解決你所建議的一些事情。 –

相關問題