【问题标题】: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节点的数据。这将需要添加额外的检查以查看头部是否与搜索字符串匹配。我不知道这样会不会更干净。
  • 为什么不使用变体链表:侵入式双链表,然后移除前面的元素可以在恒定时间内完成,这比你的实现要快得多。单链表有很多限制,不能用太广。

标签: c++ linked-list nodes singly-linked-list


【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      相关资源
      最近更新 更多