从LinkedList中移除给定位置上的元素

时间:2019-02-14 22:07:05

标签: c#

我尝试删除指定节点后的元素,代码不会给我一个错误,但不会给我带来错误。

public List<int> list;
    public class Node
    {
        public object Cont;
        public Node Next;
    }
    public Node head;

    linkedlist()
    {
        head = null;
    }
    public linkedlist(object value)
    {
        head = new Node();
        head.Cont = value;

    }
    public void removeAfter(int nume1)
    {
        Node currentnode = head;
        int current = 0;
        while (current <= nume1 && currentnode.Next != null)
        {

            currentnode = currentnode.Next;
            current++;

        }
        currentnode = currentnode.Next;
    }

我尝试从LinkedList中删除第“ nume1”个位置上的元素。 我知道c#具有内置的LinkedList,但是我需要对此进行处理。该文件具有更多代码,但我认为这足以获得正确的答案

3 个答案:

答案 0 :(得分:0)

要删除单链接列表中另一个项目之后的一个项目,我们只需要设置Item.Next = Item.Next.Next。这有效地从列表中删除了Node处的Item.Next,因为:

  1. 如果我们在索引0处有一个“第一个”节点,那么它的Next会在索引1处指向“第二个”,而second.Next会指向“在索引2上排名第三”
  2. 因此first.Next.Next指向索引2的“第三”
  3. 设置first.Next = first.Next.Next会将“第一”的下一项更改为“第三”。

例如:

class Node
{
    public string Data { get; set; }
    public Node Next { get; set; }
}

class LinkedList
{
    public Node Head { get; private set; }

    public void Add(string data)
    {
        var node = new Node {Data = data};

        if (Head == null)
        {
            Head = node;
        }
        else
        {
            var current = Head;
            while (current.Next != null) current = current.Next;
            current.Next = node;
        }
    }

    public void RemoveAfterIndex(int index)
    {
        if (index < -1) return;

        if (index == -1)
        {
            Head = Head.Next;
            return;
        }

        var current = Head;
        var count = 0;

        while (count < index && current.Next != null)
        {
            current = current.Next;
            count++;
        }

        current.Next = current.Next?.Next;
    }

    public void WriteNodes()
    {
        var current = Head;
        var index = 0;

        while (current != null)
        {
            Console.WriteLine(current.Data.PadRight(10) + $" (index {index++})");
            current = current.Next;
        }
    }
}

如果我们想创建一个包含10个节点的列表,然后删除索引3处的节点之后的节点,则它可能类似于:

private static void Main()
{
    var linkedList = new LinkedList();

    for (int i = 0; i < 10; i++)
    {
        linkedList.Add($"Item #{i + 1}");
    }

    linkedList.WriteNodes();

    var dash = new string('-', 25);
    Console.WriteLine($"{dash}\nCalling: RemoveAfterIndex(3)\n{dash}");

    linkedList.RemoveAfterIndex(3);
    linkedList.WriteNodes();

    GetKeyFromUser("\nDone! Press any key to exit...");
}

输出

![![![![enter image description here

答案 1 :(得分:0)

在单链接列表中,您可以通过将元素n上的Next设置为元素n-1来删除元素n+1。由于每个元素都有对下一个元素的引用,因此您需要遍历列表,直到找到元素n为止,同时保留上一个元素。然后,从列表中剪切元素只是一个简单的任务。

在代码中,它类似于:

public void RemoveAt(int position)
{
    // reference to current position in list
    Node current = head;

    // check for empty list
    if (current == null)
        return;

    // special case if we're removing the first item in the list
    if (position == 0)
    {
        root = current.Next;
        return;
    }

    // reference to previous position in list
    Node previous = null;

    // scan through the array to locate the item to remove
    for (int i = 0; i < position && current != null; i++)
    {
        // update previous reference
        previous = current;
        // step to next element in list
        current = current.Next;
    }

    if (previous != null && current != null)
    {
        previous.Next = current.Next;
    }
}

答案 2 :(得分:-3)

你在这里怎么说:

    currentnode = currentnode.Next;

您应该考虑这样说:

    currentnode.Next = currentnode.Next?.Next;

考虑一下,要删除列表中的第5个节点,您要使第4个节点的.Next属性指向节点6。如果您正在查看第4个节点,则希望其.Next(指向5)成为.Next.Next(指向5.指向6)。

如果我们位于列表的末尾,则第一个?之后的.Next可以帮助我们。如果我们正在查看列表中的最后一项,则.Next为null,因此调用.Next.Next将导致NullReferenceException。 ?通过实现第一个.Next为空,而不是尝试对空值进行评估来对第二个.Next进行评估,从而避免了这种情况,而是尽早停止评估并在该点返回空值< / p>

从概念上讲,它等同于

    currentnode.Next = (currentnode.Next == null ? null : currentNode.Next.Next);

可以执行任意次:

a = b.C?.D?.E?.F;

如果C, D, E中的任何一个为null,则a最终将为null,而不会引起异常。您无需在F之后使用它,因为如果只有最后一件事为null,则不会发生异常-我们不会访问null F

的任何方法或属性

其他几点:

Microsoft自己的LinkedList具有一种根据位置删除节点的方法,称为RemoveAt。它比RemoveAfter更有用,因为if可以删除列表中的第一个节点,而RemoveAfter则不能,除非您采取有点违反直觉的方法,即提供小于起始索引的任何索引都将删除第一个节点(例如RemoveAfter(-1))。您可以创建一个RemoveBefore或RemoveFirst,但是它确实增加了一些不必要的复杂性。通常,如果进行重新实现框架中已经存在的类的学术研究,将您的方法建模为现有方法是明智的想法,那么这对于“ Microsoft方式”来说是一个很好的整体选择,其中框架是书面的;如果您正在编写供他们使用的库,则习惯于“微软方式”的其他开发人员将不胜感激。

您的命名约定(方法的小写第一个字母)是Java形式,我确实想知道您是否使用Java但出于某些原因将其标记为c#。我不确定java中是否存在null促进?,如果不存在inline-if,则最后给出的形式也可以正常工作。