LinkedList“节点跳转”

时间:2009-08-22 05:58:02

标签: c++

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

酒厂对象的属性通过酒厂ctor传递,然后通过main中的这些调用传递到list::insert函数:

//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));

然后调用酒厂ctor,我分配私人指针memembers:

//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将拥有thrid酒庄。 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;
};

这可能有点重要,它是节点ctor的主体:

//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.  

}

3 个答案:

答案 0 :(得分:2)

我认为问题出在这里:

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

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

答案 1 :(得分:1)

主要问题是当你插入节点时总是设置

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

因此第二个节点被适当填充。然后第三个出现并且对第二个节点进行ovrwrit,第二个节点消失为遗忘。

答案 2 :(得分:0)

你的构造函数没有关系,但首要的是分配逻辑中的这个错误:

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

在这里,您始终将头节点(第二个节点)的下一个节点设置为新节点。这就是为什么列表中的第二个节点始终是最新的节点。

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

这样你的作业就是:

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;

在我看来是好的风格,但是不要忘记你实际上没有用这个来释放数据,如果这是你的意图: - )

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