我尝试删除指定节点后的元素,代码不会给我一个错误,但不会给我带来错误。
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,但是我需要对此进行处理。该文件具有更多代码,但我认为这足以获得正确的答案
答案 0 :(得分:0)
要删除单链接列表中另一个项目之后的一个项目,我们只需要设置Item.Next = Item.Next.Next
。这有效地从列表中删除了Node
处的Item.Next
,因为:
0
处有一个“第一个”节点,那么它的Next
会在索引1
处指向“第二个”,而second.Next
会指向“在索引2
上排名第三” first.Next.Next
指向索引2
的“第三” 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...");
}
输出
答案 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,则最后给出的形式也可以正常工作。