C++ LinkedList“;节点跳转“;

C++ LinkedList“;节点跳转“;,c++,C++,试图找出为什么我的list()类指针被第三个节点覆盖。插入函数(如下)中发生的情况是,第三次调用插入函数myheadByName->nextByName节点指针时,它会被第三个节点覆盖,此时它应该指向第二个节点。所以你可以猜到第四个节点被第五个节点覆盖,第六个节点被第七个节点覆盖,因此节点中的“跳转” winery对象的属性通过winery ctor传递,然后通过main中的以下调用传递到list::insert函数: //main.cpp //the attributes of the win

试图找出为什么我的
list()
类指针被第三个节点覆盖。插入函数(如下)中发生的情况是,第三次调用插入函数my
headByName->nextByName
节点指针时,它会被第三个节点覆盖,此时它应该指向第二个节点。所以你可以猜到第四个节点被第五个节点覆盖,第六个节点被第七个节点覆盖,因此节点中的“跳转”

winery对象的属性通过winery 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));
然后调用winery ctor,我在其中分配私有指针成员:

//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;
}
然后是手头的问题:如果您可以想象这个函数已经被调用了两次,那么当前的_节点将拥有第三个winery
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.  

}

我认为问题在于:

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

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

我认为问题在于:

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

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

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

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

因此,第二个节点被适当地填充。然后第三个节点出现,OVR写入第二个节点,第二个节点消失在遗忘中。

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

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

因此,第二个节点被适当地填充。然后第三个出现,OVR写入第二个节点,第二个节点消失在遗忘中。

您的构造函数没有关联,但首先突出的是赋值逻辑中的错误:

headByName->nextByName     = next_node;
headByRating->nextByRating = next_node;
在这里,您总是将头部节点的下一个节点(第二个节点)设置为新节点所在的任何节点。这就是为什么列表中的第二个节点总是最新的

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

因此,您的任务将改为:

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

tail_pointer = current_node;
其次,do/while循环是不必要的
headByName
headByRating
将始终设置为指向新分配的节点
当前_节点
,这意味着

while ( headByName == NULL || headByRating )
将始终中断循环(当然前提是您没有耗尽内存)

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

链表插入是常数时间,O(1),因为您不必在循环中迭代任何内容-您总是确切地知道在哪里操作:
tail\u指针

此外,这:

next_node    = NULL;
current_node = NULL;
在我看来,这是一种很好的风格,但别忘了,如果这是您的意图,那么您实际上并没有用它来释放数据:-)


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

您的构造函数没有关联,但首先突出的是赋值逻辑中的错误:

headByName->nextByName     = next_node;
headByRating->nextByRating = next_node;
在这里,您总是将头部节点的下一个节点(第二个节点)设置为新节点所在的任何节点。这就是为什么列表中的第二个节点总是最新的

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

因此,您的任务将改为:

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

tail_pointer = current_node;
其次,do/while循环是不必要的
headByName
headByRating
将始终设置为指向新分配的节点
当前_节点
,这意味着

while ( headByName == NULL || headByRating )
将始终中断循环(当然前提是您没有耗尽内存)

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

链表插入是常数时间,O(1),因为您不必在循环中迭代任何内容-您总是确切地知道在哪里操作:
tail\u指针

此外,这:

next_node    = NULL;
current_node = NULL;
在我看来,这是一种很好的风格,但别忘了,如果这是您的意图,那么您实际上并没有用它来释放数据:-)

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