【问题标题】:Attempted insert node leads to infinite linked list [closed]尝试插入节点导致无限链表[关闭]
【发布时间】:2016-11-09 17:19:47
【问题描述】:

我试图在链表中找到一个名称后将一个节点插入到链表中。 我的问题是,当我打印出链接列表时,它会打印节点,包括包含名称的节点,然后无限输出我插入的节点。任何帮助将不胜感激。谢谢!

(一些额外的信息),(指针student已经指向一个动态创建的节点)。 :)

bool StudentLinkedList::insertStudentAfter(StudentNode* student, string _name)
{
StudentNode* curr = headP;
StudentNode* prev = headP;
while (curr != NULL)
{
    if (curr->getName() == _name)
    {


        StudentNode* dummy = curr -> getnext();

        curr->setNext(student);
        prev = prev->getnext();

        curr=curr ->getnext();
        curr->setNext(dummy);

        prev = curr;
        curr = curr->getnext();


       length++;
        return true;
    }
    prev = curr;
    curr = curr->getnext();
}
return false;

}

【问题讨论】:

  • 调试器是解决此类问题的正确工具。 询问 Stack Overflow 之前,您应该逐行浏览您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。
  • @Bloggs 为什么一个函数用大写字母命名,如 setNext 而另一个用小写字母命名为 getnext?
  • while (curr != NULL) 将非常非常困难,而在插入的某处没有设置为 NULL
  • @πάνταῥεῖ 我已经逐行检查了我的代码,相信我,我正在尝试使用堆栈溢出作为最后的手段。我的调试器在 vc++ 上无法正常工作
  • @VladfromMoscow 我只是出于个人喜好将它们命名为这样有助于我更好地看到它们:)

标签: c++ pointers memory linked-list insert


【解决方案1】:

您只需在 curr 和 prev 之间插入新节点

如果你真的很想感谢,请接受并支持答案

bool StudentLinkedList::insertStudentAfter(StudentNode* student, string _name) 
{ 
StudentNode* curr = headP;
StudentNode* prev = headP; 
while (curr != NULL) 
{ 
if (curr->getName() == _name)
{ 
student->setNext(curr->getnext()); 
curr->setNext(student); 
length++; 
return true;
} 
prev = curr; 
curr = curr->getnext(); 
} 
return false;
}

【讨论】:

    【解决方案2】:

    你的函数太复杂了。函数越复杂,bug 越多,越难阅读。:)

    函数可以写成如下方式。我假设定义了以下函数

    getNext, setNext, getPrev, setPrev
       ^^^^
    

    给你。

    bool StudentLinkedList::insertStudentAfter( StudentNode *student, 
                                                const std::string &name )
    {
        StudentNode *current = headP;
    
        while ( current != nullptr && current->getName() != name ) 
        {
            current = current->getNext();
        }
    
        bool success = current != nullptr;
    
        if ( success )
        {
            student->setPrev( current );
            student->setNext( current->getNext() );
    
            if ( current->getNext() != nullptr ) 
            {
                current->getNext()->setPrev( student );
            }
    
            current->setNext( student );
        }
    
        return success;
    }
    

    考虑到如果列表还有一个名为tail的数据成员,那么如果current->getNext等于nullptr,函数也必须更改tail变量。

    例如

            if ( current->getNext() != nullptr ) 
            {
                current->getNext()->setPrev( student );
            }
            else
            {
                tailP = student;
               //^^^^
            }
    

    这是一个演示程序,展示了如何使用您的方法定义类

    #include <iostream>
    #include <string>
    
    class StudentLinkedList
    {
    private:    
        class StudentNode
        {
        private:
            StudentNode *next;
            StudentNode *prev;
            std::string name;
    
        public:
            StudentNode( const std::string &name ) 
                : next( nullptr ), prev( nullptr ), name( name ) {}
    
            StudentNode * getNext() const { return next; }
            StudentNode * getPrev() const { return prev; }
            const std::string & getName() const { return name; }
    
            void setNext( StudentNode *student ) { next = student; }
            void setPrev( StudentNode *student ) { prev = student; }
        } *head = nullptr, *tail = nullptr;
    
    public:
        StudentLinkedList() = default;
        StudentLinkedList( const StudentLinkedList & ) = delete;
        StudentLinkedList & operator =( const StudentLinkedList & ) = delete;
        ~StudentLinkedList()
        {
            while ( head != nullptr)
            {
                StudentNode *tmp = head;
                head = head->getNext();
                delete tmp;
            }
    
            tail = head;
        }
    
        void appendStudent( const std::string &name )
        {
            StudentNode *student = new StudentNode( name );
            appendStudent( student );
        }
    
        void insertStudentAfter( const std::string &current_name, 
                                 const std::string &new_name )
        {
            StudentNode *student = new StudentNode( new_name );
            insertStudentAfter( student, current_name );
        }
    
        friend std::ostream & operator <<( std::ostream &os, const StudentLinkedList &lsdt );   
    
    private:
        void appendStudent( StudentNode *student )
        {
            if ( tail == nullptr )
            {
                head = tail = student;
            }
            else
            {
                tail->setNext( student );
                tail = tail->getNext();
            }
        }
    
        bool insertStudentAfter( StudentNode *student, const std::string &name )
        {
            StudentNode *current = head;
    
            while ( current != nullptr && current->getName() != name ) 
            {
                current = current->getNext();
            }
    
            bool success = current != nullptr;
    
            if ( success )
            {
                student->setPrev( current );
                student->setNext( current->getNext() );
    
                if ( current->getNext() != nullptr ) 
                {
                    current->getNext()->setPrev( student );
                }
                else
                {
                    tail = student;
                }
    
                 current->setNext( student );
            }
    
            return success;
        }
    };
    
    std::ostream & operator <<( std::ostream &os, const StudentLinkedList &lst )
    {
        for ( StudentLinkedList::StudentNode *current = lst.head; 
             current != nullptr; 
             current = current->getNext() )
        {
            os << current->getName() << ' ';
        }
    
        return os;
    }
    
    int main() 
    {
        const size_t N = ( 'Z' - 'A' + 1 ) / 2;
    
        StudentLinkedList students;
    
        for ( size_t i = 0; i < N; i++ ) 
        {
            char name[2] = { char( 'A' + 2 * i ) };
    
            students.appendStudent( name );
        }       
    
        std::cout << students << std::endl;
    
        for ( size_t i = 0; i < N; i++ ) 
        {
            char new_name[2] = { char( 'A' + 2 * i + 1 ) };
            char current_name[2] = { char( 'A' + 2 * i ) };
    
            students.insertStudentAfter( current_name, new_name );
        }       
    
        std::cout << students << std::endl;
    
        return 0;
    }
    

    程序输出是

    A C E G I K M O Q S U W Y 
    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
    

    【讨论】:

      猜你喜欢
      • 2016-02-22
      • 2016-01-16
      • 2021-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-26
      • 2013-02-06
      • 1970-01-01
      相关资源
      最近更新 更多