C# 从单链表中删除节点

C# 从单链表中删除节点,c#,linked-list,C#,Linked List,在我看来,你可以做到: 查找要删除的节点 node.previous.next=node.next node.next.previous=node.previous node.previous=null node.next=null 如果您处于某个位置,请处置节点 非GC环境 如果您的列表是双链接的 但是如何使用单链表呢? 我尝试了很多东西,但都没有成功:( 我只是让它删除一个特定的索引,否则它什么也不做。从列表的开头开始。保持对当前项(currentItem)和上一项(previousItem

在我看来,你可以做到:

  • 查找要删除的节点
  • node.previous.next=node.next
  • node.next.previous=node.previous
  • node.previous=null
  • node.next=null
  • 如果您处于某个位置,请处置节点 非GC环境
  • 如果您的列表是双链接的

    但是如何使用单链表呢? 我尝试了很多东西,但都没有成功:(
    我只是让它删除一个特定的索引,否则它什么也不做。从列表的开头开始。保持对当前项(
    currentItem
    )和上一项(
    previousItem
    )的引用。线性搜索要删除的项目始终与
    previousItem=currentItem,currentItem=currentItem.Next
    。如果要删除的项目是列表的标题,请将列表的标题重新指定给
    currentItem.Next
    。否则,设置
    previousItem.Next=currentItem.Next
    。如果需要ry(如您所说,在非GC环境中)处置
    currentItem

    基本上,在双链接列表的情况下,您使用
    previousItem
    来模拟
    currentItem.Previous
    的行为

    编辑:这是
    Delete
    的正确实现:

    public void Delete(int rangeStart, int rangeEnd) {
        Node previousNode = null, currentNode = Head;
        while (currentNode != null) {
            if (currentNode.Data >= rangeStart && currentNode.Data <= rangeEnd) {
                if (previousNode == null) {
                    Initial = currentNode.Next;
                }
                else {
                    previousNode.Next = currentNode.Next;
                }
            }
            else {
                previousNode = currentNode;
            }
            currentNode = currentNode.Next;
        }
    }
    
    public void Delete(int-rangeStart,int-rangeEnd){
    节点previousNode=null,currentNode=Head;
    while(currentNode!=null){
    
    如果(currentNode.Data>=rangeStart&¤tNode.Data您在尝试查找“当前节点”时跟踪最后一个节点


    然后,您可以将previouse.next连接到current.next,这样您就完成了

    以下代码使用递归跟踪上一个节点: 资料来源:


    您可以使用
    LinkedList
    Remove
    ;但是手动:

    • 向前迭代,直到找到要删除的节点,使前一个节点在变量中的每个点可用
    • 设置
      prev.next=node.next
    • 回家

    请记住您也去过的最后一个节点

    //PSEUDO CODE
    
    Node prevnode = null;
    foreach (node n in nodes)
    {
        if (n.name.equals(name))
        {
            if (prevnode != null)
            {
                prevnode.next = n.next;
            }
            remove n;
            break;
        }
    
        prevnode = n;
    }
    

    这是单链接列表的主要缺点。您需要有对上一个节点的引用,或者从一开始就扫描列表。

    理论上,您可以这样做从单链接列表中删除任意随机节点:

    void RemoveNode(Node toRemove)
    {
        toRemove.PointerToSomeValue = toRemove.NextNode.PointerToSomeValue ;
        toRemove.NextNode = toRemove.NextNode.NextNode ;
    
    }
    
    但是,您需要小心并发性问题。(例如,其他人有一个到您节点的链接,假设它仍然会破坏旧值(ABA问题)),并且您需要在列表末尾有一个“标记”(空)节点,您决不能尝试删除它。(因为toRemove.next.next)


    编辑:显然PoToStoMeValueE是你想保留在列表中的任何数据。实际上,你并没有删除这个节点,你基本上删除了列表中的下一个节点,哦,你得到IDEEA

    < P> >你几乎可以说是讽刺的。你应该问问我。我也在尝试修改我的单链接列表。我只是在C++中写了这个函数。似乎有效:

    void pop_back() {
        if(head == NULL) {
            return;
        }
    
        if(head->next == NULL) {
            delete head;
            head = NULL;
            return;
        }
    
        Node *iter = head;
        while(iter->next->next != NULL) {
            iter = iter->next;
        }
        delete iter->next;
        iter->next = NULL;
    }
    

    用于弹出最后一个元素,但你可以稍微修改它,以便在中间工作,我确信。C中的想法几乎是相同的。

    < P>你可以找到单独的链表的全部实现,这些函数都有加法、删除、InsertAt etc.等功能。 注意:这有一个工作的Java代码+测试类,这样你就不会错过任何由单链表组成的东西

    struct node_t {
        int data;
        struct node_t *next;
    }
    
    void delete_node( struct node_t *random) {
        struct node_t *temp;
    
        /* Save the ptr to the next node */
        temp = random->next;
    
        /* Copy stuff from the next node to this node */
        random->data = random->next->data;
        random->next = random->next->next;
    
        /* Delete the next node */
        free (temp);
    
        return;
    }
    
    在我看来,这应该适用于大多数操作系统。

    staticvoidmain(string[]args)
    
        static void Main(string[] args)
        {
            LinkedList<string> ll = new LinkedList<string>();
    
            ll.AddLast("uno");
            ll.AddLast("dos");
            ll.AddLast("tres");
    
            ll.Remove(ll.Find("uno")); // Remove
    
            foreach (string item in sl)
            {
                Console.WriteLine(item);
            }
    
            Console.ReadKey();
        }
    
    { LinkedList ll=新建LinkedList(); ll.AddLast(“uno”); ll.AddLast(“dos”); ll.AddLast(“tres”); ll.Remove(ll.Find(“uno”);//Remove foreach(sl中的字符串项) { 控制台写入线(项目); } Console.ReadKey(); }
    下面是一个在C#中从LinkedList中删除节点的有效解决方案

    • 首先,循环遍历节点,直到找到匹配的节点
    • 其次,更新上一个节点和当前节点的值
    • 若第一个节点,即前一个节点为空,则将头部指向下一个节点

      class LinkedList
      {
          private Node Head { get; set; } = null;
      
          public void Insert(int d)
          {
              Console.WriteLine("Insert : " + d);
              var newNode = new Node() { Data = d, Next = null };
              if (Head == null)
              {
                  Head = newNode;
              }
              else
              {
                  newNode.Next = Head;
                  Head = newNode;
              }
          }
      
          public void Delete(int d)
          {
              Console.WriteLine("Delete : "+d);
              var node = Head;
              Node currNode = Head;
              Node prevNode = null;
              while (node != null)
              {
                  currNode = node;
                  if (node.Data == d)
                  {
                      if(prevNode != null)
                      {
                          prevNode.Next = currNode.Next;
                      }
                      else
                      {
                          Head = Head.Next;
                      }
                      break;
                  }
                  prevNode = currNode;
                  node = node.Next;
              }
          }
      
          public void Print()
          {
              var list = Head;
              Console.Write("Elements: ");
              while (list != null)
              {
                  Console.Write(list.Data + " ");
                  list = list.Next;
              }
              Console.WriteLine();
          }
      }
      

    根据列表项的索引值从单个LinkedList中删除特定节点。下面是代码

     public void DeleteNode(int nodeIndex)
        {
            int indexCounter = 0;
            Node TempNode = StartNode;
            Node PreviousNode = null;
            while (TempNode.AddressHolder != null)
            {
                if (indexCounter == nodeIndex)
                {
                    PreviousNode.AddressHolder = TempNode.AddressHolder;
                    break;
                }
                indexCounter++;
                PreviousNode = TempNode;
                TempNode = TempNode.AddressHolder;
            }
        }
    

    完整的代码可以在

    上找到,应该检查prev是否为null!不是吗?将LinkedList称为“语言不可知论者”会有点牵强;-)@HerdplattenToni-检查编辑历史;它曾经是C#的!@Marc Gravell:我进行编辑,因为他的第一个版本的帖子似乎是在寻找想法,而不是特定语言的代码(如他关于如何为双链接列表执行此操作的演练所示)。现在他添加了代码,我又添加了标签。但是,他似乎没有使用
    LinkedList
    。这很聪明!我没有想过模仿!虽然,我似乎不工作,但如果该项目是我列表中的第一个项目?@CasperT:如果该项目是列表中的第一个项目,您只需将列表的标题重新分配给他即可
    currentItem.Next
    并在必要时处理
    currentItem
    。在这种情况下,不需要
    previousItem
    参考。我想我有点偏离了轨道。我已经更新了我的问题:)哦,如果该项目在我的列表末尾,也不会起作用:)@ CasperT:您所提供的将不起作用。请考虑1 ->2–>3>4>5,调用<代码>删除(1, 2)
    。您将以列表
    2->3->4->5
    结束,因为
    Initial
    节点将无法正确设置。这是因为当
    previousNode
    null
    时,您只需修改
    Initial
    。浏览列表中的初始项后,您将看到
    Initial
    指向包含ng 2,
    previousNode
    指向包含1的节点,
    currentNode
    指向包含2的节点。因此,下一次通过
     public void DeleteNode(int nodeIndex)
        {
            int indexCounter = 0;
            Node TempNode = StartNode;
            Node PreviousNode = null;
            while (TempNode.AddressHolder != null)
            {
                if (indexCounter == nodeIndex)
                {
                    PreviousNode.AddressHolder = TempNode.AddressHolder;
                    break;
                }
                indexCounter++;
                PreviousNode = TempNode;
                TempNode = TempNode.AddressHolder;
            }
        }