使用 C# 实现单向链表 - RemoveLast 方法
Singly Linked List Implementation using C# - RemoveLast Method
我已经使用 C# 实现了单向链表。任何人都可以查看以下代码并提出我错在哪里吗?
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
while (curNode.Next != null)
{
curNode = curNode.Next;
}
var lastNodeValue = curNode.Value;
curNode = null;
Size--;
return lastNodeValue;
}
return -1;
}
此函数不会删除最后一个节点。我无法弄清楚出了什么问题。当 while 循环结束时,我们有 curNode 中节点的引用,其 next 为 null。这意味着这是最后一个节点。最后,我将此节点设置为空。但是当我使用显示功能时。它还显示最后一个节点。这不是删除最后一个节点。
这是我的显示函数:
public string Display()
{
if (Head == null)
{
return string.Empty;
}
var curNode = Head;
var builder = new StringBuilder();
while (curNode.Next != null)
{
builder.Append($"{curNode.Value} ");
curNode = curNode.Next;
}
builder.Append($"{curNode.Value} ");
return builder.ToString();
}
您需要使前一个节点的 curNode.Next 值为空。
'curNode' 是一个局部变量,将它设置为 null 除了可能会延长其 GC 寿命外不会做任何事情。
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
var previousNode = null;
while (curNode.Next != null)
{
previousNode = curNode;
curNode = curNode.Next;
}
var lastNodeValue = curNode.Value;
if (previousNode == null)
Head = null;
else
previousNode.Next = null;
Size--;
return lastNodeValue;
}
return -1;
}
您需要转到 last-but-one 节点,并将其 Next
更改为 null:
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
while (curNode.Next?.Next != null)
{
curNode = curNode.Next;
}
var lastNodeValue = curNode.Next?.Value ?? -1;
curNode.Next = null;
Size--;
return lastNodeValue;
}
return -1;
}
请注意,如果您还希望将 Head
设置为 null(如果它是唯一的节点),那么您可以这样做:
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
while (curNode.Next?.Next != null)
{
curNode = curNode.Next;
}
int lastNodeValue;
if (Head.Next == null)
{
lastNodeValue = Head.Value;
Head = null;
}
else
{
lastNodeValue = curNode.Next?.Value ?? -1;
}
curNode.Next = null;
Size--;
return lastNodeValue;
}
return -1;
}
不过我不得不说,这个 Head
属性 看起来有点可疑 - 它可能应该属于另一个 class.
[x] -> [x] -> [x] -> null
^
curNode (becomes null)
^
this reference still exists
在执行 curNode = null
时,您不会更改列表中的任何引用。 curNode
变量只改变,它指向操作前的最后一个元素,然后变为null。
尝试始终引用最后一个节点:
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
// Corner case when there is only one node in the list
if (Head.Next == null)
{
Head = null;
Size--;
return curNode.value;
}
var beforeLastNode = curNode;
curNode = curNode.Next;
while (curNode.Next != null)
{
beforeLastNode = curNode;
curNode = curNode.Next;
}
var lastNodeValue = curNode.Value;
beforeLastNode.Next = null;
Size--;
return lastNodeValue;
}
return -1;
}
好的各位,在你们的帮助下,我重写了这个方法,满足了所有的要求,如果链表只有一个节点,则设置为HeadNode null。所以我们开始吧:
public int RemoveLast()
{
if (HeadNode != null)
{
var currNode = HeadNode;
var prevNode = HeadNode;
if (HeadNode.Next == null)
{
HeadNode = null;
Size--;
return currNode.Value;
}
while (currNode.Next != null)
{
prevNode = currNode;
currNode = currNode.Next;
}
prevNode.Next = null;
Size--;
return currNode.Value;
}
return -1;
}
感谢在此主题中做出贡献的所有人。快乐编码:)
我已经使用 C# 实现了单向链表。任何人都可以查看以下代码并提出我错在哪里吗?
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
while (curNode.Next != null)
{
curNode = curNode.Next;
}
var lastNodeValue = curNode.Value;
curNode = null;
Size--;
return lastNodeValue;
}
return -1;
}
此函数不会删除最后一个节点。我无法弄清楚出了什么问题。当 while 循环结束时,我们有 curNode 中节点的引用,其 next 为 null。这意味着这是最后一个节点。最后,我将此节点设置为空。但是当我使用显示功能时。它还显示最后一个节点。这不是删除最后一个节点。
这是我的显示函数:
public string Display()
{
if (Head == null)
{
return string.Empty;
}
var curNode = Head;
var builder = new StringBuilder();
while (curNode.Next != null)
{
builder.Append($"{curNode.Value} ");
curNode = curNode.Next;
}
builder.Append($"{curNode.Value} ");
return builder.ToString();
}
您需要使前一个节点的 curNode.Next 值为空。 'curNode' 是一个局部变量,将它设置为 null 除了可能会延长其 GC 寿命外不会做任何事情。
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
var previousNode = null;
while (curNode.Next != null)
{
previousNode = curNode;
curNode = curNode.Next;
}
var lastNodeValue = curNode.Value;
if (previousNode == null)
Head = null;
else
previousNode.Next = null;
Size--;
return lastNodeValue;
}
return -1;
}
您需要转到 last-but-one 节点,并将其 Next
更改为 null:
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
while (curNode.Next?.Next != null)
{
curNode = curNode.Next;
}
var lastNodeValue = curNode.Next?.Value ?? -1;
curNode.Next = null;
Size--;
return lastNodeValue;
}
return -1;
}
请注意,如果您还希望将 Head
设置为 null(如果它是唯一的节点),那么您可以这样做:
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
while (curNode.Next?.Next != null)
{
curNode = curNode.Next;
}
int lastNodeValue;
if (Head.Next == null)
{
lastNodeValue = Head.Value;
Head = null;
}
else
{
lastNodeValue = curNode.Next?.Value ?? -1;
}
curNode.Next = null;
Size--;
return lastNodeValue;
}
return -1;
}
不过我不得不说,这个 Head
属性 看起来有点可疑 - 它可能应该属于另一个 class.
[x] -> [x] -> [x] -> null
^
curNode (becomes null)
^
this reference still exists
在执行 curNode = null
时,您不会更改列表中的任何引用。 curNode
变量只改变,它指向操作前的最后一个元素,然后变为null。
尝试始终引用最后一个节点:
public int RemoveLast()
{
if (Head != null)
{
var curNode = Head;
// Corner case when there is only one node in the list
if (Head.Next == null)
{
Head = null;
Size--;
return curNode.value;
}
var beforeLastNode = curNode;
curNode = curNode.Next;
while (curNode.Next != null)
{
beforeLastNode = curNode;
curNode = curNode.Next;
}
var lastNodeValue = curNode.Value;
beforeLastNode.Next = null;
Size--;
return lastNodeValue;
}
return -1;
}
好的各位,在你们的帮助下,我重写了这个方法,满足了所有的要求,如果链表只有一个节点,则设置为HeadNode null。所以我们开始吧:
public int RemoveLast()
{
if (HeadNode != null)
{
var currNode = HeadNode;
var prevNode = HeadNode;
if (HeadNode.Next == null)
{
HeadNode = null;
Size--;
return currNode.Value;
}
while (currNode.Next != null)
{
prevNode = currNode;
currNode = currNode.Next;
}
prevNode.Next = null;
Size--;
return currNode.Value;
}
return -1;
}
感谢在此主题中做出贡献的所有人。快乐编码:)