在单链表中的特定节点之前插入一个节点

Posted

技术标签:

【中文标题】在单链表中的特定节点之前插入一个节点【英文标题】:Inserting a node before a specific node in a singly linked list 【发布时间】:2021-08-02 21:11:03 【问题描述】:

我已经实现了一种在特定节点之前插入新节点的方法。

#ifndef FORWARD_SINGLY_LINKED_LIST_H
#define FORWARD_SINGLY_LINKED_LIST_H

#include <cstdlib>
#include <string.h>
#include <iostream>

namespace forward_singly_linked_list 
    typedef struct Node 
        std::string data;
        struct Node *nextPointer;
     Node;

    typedef Node *NodeP;

    class LinkedList 
    private:
        int elementsCount;
        Node *head;

    public:
        LinkedList() 
            head = NULL;
            elementsCount = 0;
        

        int get_length() const
        
            return elementsCount;
        

        // ... ... ...

        void add_before(std::string value, std::string before)
        
            // empty an area in the memory, and
            // save the address of the empty area in 'newNode'
            Node *newNode = new Node();
            // assign 'value' to the 'data' section of the
            // area pointed by 'newNode'
            newNode->data = value;

            Node * copyOfHead = head;

            if (copyOfHead == nullptr)
            
                // the list is empty.
                // there is no possibility to find 'before'.
                // so, return.
                return;
            
            else
            
                bool found = false;
                Node * previousNode = nullptr;
                while (copyOfHead != nullptr)
                
                    if (copyOfHead->data == before)
                    
                        found = true;
                        break;
                    
                    else
                    
                        previousNode = copyOfHead;
                        copyOfHead = copyOfHead->nextPointer;
                    
                

                if (!found)
                
                    return;
                

                if (previousNode != nullptr)
                
                    newNode->nextPointer = previousNode->nextPointer;
                    previousNode->nextPointer = newNode;
                
                else
                
                    newNode->nextPointer = head;
                    head = newNode;
                
            

            elementsCount++;
        
        

        // ... ... ...

        void print() 
            Node *copyOfHead = head;
            while (copyOfHead != NULL) 
                std::cout << copyOfHead->data;
                copyOfHead = copyOfHead->nextPointer;
            
            std::cout<<"\n\n";
        
    public:
        static int Test() 
            forward_singly_linked_list::LinkedList list;

            list.print();
//            list.add_at_tail("A");
//            list.add_at_tail("B");
//            list.add_at_tail("C");
            list.print();

            list.add_at("-XXX-", 1);
            list.print();

            return 0;
        
    ;

#endif

就我个人而言,我不喜欢它,因为它使用了一个额外的指针previousNode。我觉得它可以改进。

如何改进实施?

【问题讨论】:

如果您需要帮助改进工作代码,您应该将其发布到CodeReview.SE。如果您决定这样做,请在此处删除问题。 就个人而言,我不喜欢它。我感觉它可以改进。 -- 你为什么认为它需要改进?甚至std::forward_list 也没有现成的函数来在另一个之前插入一个项目,因为这是单链表的本质。您基本上必须为单链表编写某种循环检查代码才能在另一个项目之前插入一个项目。 如果你想删除previousNode,你可能不得不切换while循环来检查next节点的数据。这将需要添加额外的检查以查看头部是否与搜索字符串匹配。我不知道这样会不会更干净。 为什么不使用变体链表:侵入式双链表,然后移除前面的元素可以在恒定时间内完成,这比你的实现要快得多。单链表有很多限制,不能用太广。 【参考方案1】:

这个想法是将前一个节点链接到输入/目标节点,然后将目标/输入节点链接到当前节点。 这是我使用简单循环索引(i)而不是使用额外指针的代码

void Sll::add_at_index( int ind , int value )

 Node *target = new Node( value ) ;

 if( ind == 1)

      target->next = head ;
      head = target ;

 else if( ind == length)

      tail->next = target ;
      tail = target ;
      tail->next = nullptr ;

 else

      Node *curr =head ;
      for( int i = 1 ; i < length ; i++ )

           if( i+1 == ind)

                Node *Mynext = curr->next ;
                curr->next = target ;
                target->next = Mynext ;
                break ;
           
           curr = curr->next ;

      
 
 length++ ;

【讨论】:

【参考方案2】:

成为二星级程序员

void add_before(std::string value, std::string_view before) 
    auto p = &head;
    while (*p && (*p)->data != before)
        p = &(*p)->nextPointer;
    if (!*p)
        return;
    *p = new Node 
        .data = std::move(value),
        .nextPointer = *p,
    ;
    ++elementsCount;

【讨论】:

以上是关于在单链表中的特定节点之前插入一个节点的主要内容,如果未能解决你的问题,请参考以下文章

[算法]向有序的环形单链表中插入新节点

单链表LRU

试写出在不带头结点的单链表的第i个元素之前插入一个元素的算法 麻烦帮我修改下

无头结点单链表 在头指针处插入元素

2-12在一个单链表head中,若要在指针p所指结点后插入一个q指针所指结点,则执行()?

每天进步一点点之带头节点单链表