从单个链接列表中删除节点

时间:2009-09-16 13:00:55

标签: c# linked-list

据我所知,你可以这样做:

  1. 找到要删除的节点。
  2. node.previous.next = node.next
  3. node.next.previous = node.previous
  4. node.previous = null
  5. node.next = null
  6. 如果您在某处,请处置节点 非GC环境
  7. 如果您的列表是双重关联的。

    但是如何使用单个链表进行操作呢? 我尝试了很多东西,但没有用:( 我只是简单地删除一个特定的索引,或者根本不做任何事情

13 个答案:

答案 0 :(得分:11)

从列表的开头开始。保持对当前项(currentItem)和上一项(previousItem)的引用。线性搜索要删除的项目,始终使用previousItem = currentItem, currentItem = currentItem.Next。如果要删除的项目是列表的头部,请将列表的头部重新分配给currentItem.Next。否则,请设置previousItem.Next = currentItem.Next。如有必要(如您所说,在非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;
    }
}

答案 1 :(得分:5)

当您尝试查找“当前节点”时,您会跟踪最后一个节点。

然后你可以将previouse.next连接到current.next并完成

答案 2 :(得分:3)

好吧,你可以使用LinkedList<T>Remove;但是手动:

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

答案 3 :(得分:2)

以下代码使用递归来跟踪上一个节点: 资料来源:http://www.cs.bu.edu/teaching/c/linked-list/delete/

nodeT *ListDelete(nodeT *currP, elementT value)
{
  /* See if we are at end of list. */
  if (currP == NULL)
    return NULL;

  /*
   * Check to see if current node is one
   * to be deleted.
   */
  if (currP->element == value) {
    nodeT *tempNextP;

    /* Save the next pointer in the node. */
    tempNextP = currP->next;

    /* Deallocate the node. */
    free(currP);

    /*
     * Return the NEW pointer to where we
     * were called from.  I.e., the pointer
     * the previous call will use to "skip
     * over" the removed node.
     */
    return tempNextP;
  }

  /*
   * Check the rest of the list, fixing the next
   * pointer in case the next node is the one
   * removed.
   */
  currP->next = ListDelete(currP->next, value);


  /*
   * Return the pointer to where we were called
   * from.  Since we did not remove this node it
   * will be the same.
   */
  return currP;
}

答案 4 :(得分:2)

您可以在此处找到包含Add,Remove,InsertAt等所有功能的单一链接列表的全面实现。 http://tech.bragboy.com/2010/01/linked-lists.html 注意:这有一个可用的Java代码+测试类,因此您不会错过任何单链表的组成,

答案 5 :(得分:1)

记住你最后一个节点。

//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;
}

答案 6 :(得分:1)

这是单链表的主要弱点。您需要引用前一个节点,或者从头开始扫描列表。

答案 7 :(得分:0)

几乎讽刺的是你应该问这个问题。我也试图刷新我的单链表。我刚用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#中的想法几乎相同。

答案 8 :(得分:0)

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;
}

在我看来,这应该适用于大多数操作系统。

答案 9 :(得分:0)

    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();
    }

答案 10 :(得分:0)

这是一个在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();
        }
    }
    

答案 11 :(得分:0)

根据List项的索引值从单个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;
        }
    }

完整代码可在http://fumycoder.com/2017/09/06/linked-list/

找到

答案 12 :(得分:-1)

在理论中,您可以执行此操作以从单个链接列表中删除任何随机节点:

void RemoveNode(Node toRemove)
{
    toRemove.PointerToSomeValue = toRemove.NextNode.PointerToSomeValue ;
    toRemove.NextNode = toRemove.NextNode.NextNode ;

}

但是,你需要小心确定问题。 (即,其他人有一个指向您的节点的链接,假设它仍然掠过旧值(ABA问题)),并且您需要在列表末尾有一个“标记”(空)节点,您绝不能尝试删除。(因为toRemove.next.next)

编辑:显然,PointerToSomeValue是您要保留在列表中的任何数据。而你实际上并没有删除节点,你基本上是删除列表中的下一个节点,哦,好吧..你得到了ideea