【问题标题】:C# how to insert a node in LinkedList on a specific indexC#如何在特定索引的LinkedList中插入一个节点
【发布时间】:2018-09-02 22:09:06
【问题描述】:

我有一个学校作业,该作业的一部分是在其他两个节点之间插入一个链表节点。这就是方法。

public static void insert(LinkedList<Person> list, int index, Person data)
    {

    }

我读过一些关于 LinkedList 的文章,我发现每个链表都需要一个头和一个尾。我只是不确定如何实现它,因为我们只允许使用 LinkedList&lt;T&gt;LinkedListNode&lt;T&gt; 而没有它们提供的大部分功能。

我想我必须使用 while 循环来获取给定的索引,但我不知道如何在 LinkedList 中移动。

public static void insert(LinkedList<Person> list, int index, Person data)
    {
        int counter = 0;

        while (counter <= index)
        {
            if (counter == index)
            {

            }

            counter = counter + 1;
        }
    }

所以我想知道如何在特定索引上的LinkedList 中插入data,以及如何在这种情况下创建头部和尾部。 注意:我不允许更改方法的签名。

【问题讨论】:

标签: c# linked-list


【解决方案1】:

这是一个有趣的任务。我想知道您的老师是否知道 .Net Frameworks 源代码是公开的。尽管您被禁止使用LinkedList&lt;T&gt;.AddAfter 之类的方法,但您可以随意查看源代码并了解该方法是如何实现的,并且可以说...只是复制代码? ;-)

看看:https://referencesource.microsoft.com/#System/compmod/system/collections/generic/linkedlist.cs,3fc9552feecc5b5c

在那里你会看到这个AddAfter-Method的实现:

public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode) {
    ValidateNode(node);
    ValidateNewNode(newNode);
    InternalInsertNodeBefore(node.next, newNode);
    newNode.list = this;
}

您感兴趣的部分是由AddAfter()-方法调用的内部方法InternalInsertNodeBefore()

它位于同一个类中 - 您可以通过键入 ctrl+f 找到它:

private void InternalInsertNodeBefore(LinkedListNode<T> node, LinkedListNode<T> newNode) {
    newNode.next = node;
    newNode.prev = node.prev;
    node.prev.next = newNode;
    node.prev = newNode;            
    version++;
    count++;
}

在那里你会看到它是如何完成的,并且可能会得到一些“灵感”。手动设置countversion会有问题。它们只能由 LinkedList 中的函数设置。我认为您将无法设置count-变量。但是,以这种方式添加新元素应该可以。


编辑 1当然,您必须首先在所需索引处获取列表的当前元素。您将通过拨打list.ElementAt(index) 获得它。它将返回一个LinkedListNode&lt;Person&gt; 节点。连同您的新人员节点,您可以调用InternalInsertNodeBefore()。如您所见,您不需要任何循环。


编辑 2看来我必须道歉。我还没有看到NextPrevious-LinkedListNode&lt;T&gt; 的值也是只读值。见:https://referencesource.microsoft.com/#System/compmod/system/collections/generic/linkedlist.cs,08181ebdd4cdf907

此外,Microsoft 还密封了该课程。所以不可能通过新类继承它并覆盖 NextPrevious 以添加 setter 方法。看来您必须自己实现一个全新的 LinkedList- 和 LinkedListNode-Class。这个话题已经有问题了:Creating a very simple linked list

这是我想到的代码。但是它不会工作,因为nextprevhead 是内部对象。他们有 NextPreviousFirst 等公共参考资料,但它们是只读的。

public static void insert(LinkedList<Person> list, int index, Person data)
{
    int currentIndex = 0;
    var currentNode = list.head;
    if (index >= 0)
    {
        while (currentNode != null && currentIndex <= index)
        {
            if (currentIndex == index)
            {
                data.next = currentNode;
                data.prev = currentNode.prev;
                currentNode.prev.next = data;
                currentNode.prev = data; 
            }
            currentIndex++;
            currentNode = currentNode.next;
        }
    }
}

【讨论】:

  • 那会很好用,问题是,我什至不允许使用任何复杂的内置函数。
  • 我的解决方案中没有使用复杂的内置函数。你指的是哪一个?
  • list.ElementAt(index)
  • 好的——即使不使用list.ElementAt(index),我也知道如何处理这个问题,我会更新我的答案——但你不应该忘记这是一项提高你技能的任务。您应该尝试自己找到解决方案。我将在 6 小时内更新我的答案。这应该是足够的时间。这里有一些提示: 你需要一个循环;搜索“在c#中遍历LinkedList”
  • 嘿@Fihii。似乎我错过了一些尴尬的事实。我认为在不使用类的给定方法的情况下手动将新节点插入 LinkedList 是不可能的。我用所有细节完成了我的回答。但是,现在您应该对链表有足够的了解,以便开发自己的列表和节点类来完成您的任务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 2021-12-02
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多