2009-08-22 71 views
0

试图找出为什么我的list()类指针正在被第三个节点覆盖。插入函数(下面)中发生的情况是,第三次插入函数被调用时,我的headByName->nextByName节点指针被第三个节点覆盖,当它指向第二个节点时。因此,你可以猜测第4节点被第5节覆盖,第6节节点被第7节覆盖,因此节点中的“跳”。LinkedList“节点跳转”

//main.cpp 
//the attributes of the winery object are the paramaters, name, location, acres, rating: 
list *listPtr = new list(); 
wineries->insert(winery("Lopez Island Vinyard", "San Juan Islands", 7, 95)); 
wineries->insert(winery("Gallo", "Napa Valley", 200, 25)); 
wineries->insert(winery("Cooper Mountain", "Willamette Valley", 100, 47)); 

然后酒厂构造函数被调用,其中我分配专用指针低级用户隔离:

酒厂对象的属性是通过酒厂构造函数,然后通过这些调用在主的list::insert函数传递

//winery.cpp 
winery::winery(const char * const name, const char * const location, const int acres, const int rating) 
    : m_acres(acres), m_rating(rating) 
{ 
    if (name) 
    { 
     size_t len = strlen(name) +1; 
     m_name = new char[len]; 
     strcpy_s(m_name, len, name); 
    } 
    else 
     m_name = NULL; 

    if (location) 
    { 
     size_t len = strlen(location) +1; 
     m_location = new char[len]; 
     strcpy_s(m_location, len, location); 
    } 
    else 
     m_location = NULL; 
} 

然后到手边的问题:如果你可以想象这个功能已被调用两次,current_node将有第三酒庄。 headByName将拥有第一个节点并且[+],headByName->next将拥有第三个节点。我需要headByName->next获得第二名。我只是想知道为什么它已被覆盖..

// list.cpp 
void list::insert(const winery& winery) 
{ 
    node *current_node = new node(winery); // the third wineries info! 
    node *next_node  = NULL; 
    list *list_ptr  = NULL; 
    do 
    { 
     if (headByName == NULL || headByRating == NULL) // then we are here for the first item 
     { 
      headByName = current_node; // the list ptrs have a node address. 
      headByRating = current_node; 
     } 
     else 
     {   

      next_node     = current_node; 
// transfer by the next call in main. 
      headByName->nextByName  = next_node; 
      headByRating->nextByRating = next_node; 

     } 
    } while (headByName == NULL || headByRating == NULL); 

    next_node = NULL; 
    current_node = NULL; 
} 

有人可以找到我的第二个节点? 噢,那是提供给我的指点:

struct node 
{ 
    winery item; 
    node * nextByName; 
    node * nextByRating; 
}; 

class list 
{ 
    ... 
private: 
    node * headByName; 
    node * headByRating; 
}; 

,这可能是一些重要的节点构造函数的其身体:

//list.cpp 
list::node::node(const winery &winery) : 
nextByName(NULL), nextByRating(NULL), item(winery.getName(), 
winery.getLocation(), winery.getAcres(), winery.getRating()) 
{ 
    // where the item paramters are all pub-mem functions of the winery class. 

} 

回答

2

我认为这个问题是在这里:

headByName->nextByName  = next_node; 
headByRating->nextByRating = next_node; 

您总是覆盖第二个节点。据我所知,你应该找到最后一个遍历整个列表并插入最后一个节点后。

1

好首要的问题是,当你插入一个节点,你总是设置

headByName->nextByName  = next_node; 
headByRating->nextByRating = next_node; 

所以第二个节点被适当地填补。然后,第三个出现并覆写第二个节点,第二个节点消失。

0

你的构造不相关但伸出的第一件事就是这个错误在分配逻辑:

headByName->nextByName  = next_node; 
headByRating->nextByRating = next_node; 

这里你总是设置头节点到下一个节点(第2节点)的任何新节点是。这就是为什么列表中的第二个节点总是最新的节点。

如果您希望将项目添加到列表的末尾,您应该保留一个指向插入最后项目的尾指针,从头项目开始。

随着你的任务将改为:

tail_pointer->nextByName = current_node; 
tail_pointer->nextByRating = current_node; 

tail_pointer = current_node; 

其次,DO/while循环是不必要的。headByNameheadByRating总是被设置为指向新分配的节点current_node,这意味着

while (headByName == NULL || headByRating) 

总是会跳出循环的(前提是你是不是跑出来的,当然内存)。

您总是通过在list :: insert中的第一个if块中使用延迟初始化来分配两个变量。

链接列表插入是恒定时间O(1),因为您不必在循环中迭代任何东西 - 您始终知道在哪里操作:tail_pointer

而且,这样的:

next_node = NULL; 
current_node = NULL; 

是良好的作风在我看来,但不要忘记,你实际上并没有重新分配这个数据来看,这是你的意图:-)

情况

保留一个始终指向最新项目的尾部指针!