完全披露:这是我班上的一个项目,但我不是要求你为我做功课。我正在寻找一个关于我似乎缺少什么的方向。
作业:来自格式化数据的文件(见下文)。您将创建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();
如果您需要我发布更多代码,请告诉我,我会这样。 同样,我觉得我要么没有正确地制作双重链接列表,要么没有正确删除它。
再次感谢!
答案 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)从不 - 所以你的名单坏了!您需要添加更新“上一个”指针的代码