C# 单链表:删除方法
我正在用C#写一个单链表,你能告诉我是否有比我现在的方法更好的删除方法吗C# 单链表:删除方法,c#,C#,我正在用C#写一个单链表,你能告诉我是否有比我现在的方法更好的删除方法吗 using System; class Node { public int data = int.MinValue; public Node m_NextNode; public Node(int data_in) { data = data_in; } public Node() { } } class LinkedList {
using System;
class Node
{
public int data = int.MinValue;
public Node m_NextNode;
public Node(int data_in)
{
data = data_in;
}
public Node()
{
}
}
class LinkedList
{
private Node m_HeadNode;
public void InsertData(int data)
{
Node aCurrentNode = m_HeadNode;
if(m_HeadNode == null)
{
m_HeadNode = new Node();
m_HeadNode.data = data;
}
else
{
while(aCurrentNode.m_NextNode != null)
aCurrentNode = aCurrentNode.m_NextNode;
aCurrentNode.m_NextNode = new Node();
aCurrentNode.m_NextNode.data = data;
}
}
public void DisplayData()
{
Node aCurrentNode = m_HeadNode;
while (aCurrentNode != null)
{
Console.WriteLine("the value is {0}", aCurrentNode.data);
aCurrentNode = aCurrentNode.m_NextNode;
}
}
public void RemoveData(int data)
{
Node aCurrentNode = m_HeadNode;
while (aCurrentNode != null)
{
//if the data is present in head
//remove the head and reset the head
if (m_HeadNode.data == data)
{
m_HeadNode = null;
m_HeadNode = aCurrentNode.m_NextNode;
}
else
{
//else save the previous node
Node previousNode = aCurrentNode;
if (aCurrentNode != null)
{
//store the current node
Node NextNode = aCurrentNode.m_NextNode;
if (NextNode != null)
{
//store the next node
Node tempNode = NextNode.m_NextNode;
if (NextNode.data == data)
{
previousNode.m_NextNode = tempNode;
NextNode = null;
}
}
aCurrentNode = aCurrentNode.m_NextNode;
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
LinkedList aLinkedList = new LinkedList();
aLinkedList.InsertData(10);
aLinkedList.InsertData(20);
aLinkedList.InsertData(30);
aLinkedList.InsertData(40);
aLinkedList.DisplayData();
aLinkedList.RemoveData(10);
aLinkedList.RemoveData(40);
aLinkedList.RemoveData(20);
aLinkedList.RemoveData(30);
aLinkedList.DisplayData();
Console.Read();
}
}
您有一条不需要的线路:
m_HeadNode = null;
m_HeadNode = aCurrentNode.m_NextNode;
在将m_HeadNode设置为其他值之前,不需要将其设置为null。我会将“如果删除head node”从while循环中拉出,使while循环更简单。只需跟踪当前和以前的节点,并在找到要删除的节点时切换引用即可
public void RemoveData(int data)
{
if (m_HeadNode == null)
return;
if (m_HeadNode.data == data)
{
m_HeadNode = m_HeadNode.m_NextNode;
}
else
{
Node previous = m_HeadNode;
Node current = m_HeadNode.m_NextNode;
while (current != null)
{
if (current.data == data)
{
// If we're removing the last entry in the list, current.Next
// will be null. That's OK, because setting previous.Next to
// null is the proper way to set the end of the list.
previous.m_NextNode = current.m_NextNode;
break;
}
previous = current;
current = current.m_NextNode;
}
}
}
RemoveData应该从列表中删除该整数的一个实例,还是所有实例?前面的方法只删除第一个,这里的方法删除了所有的
public void RemoveAllData(int data)
{
while (m_HeadNode != null && m_HeadNode.data == data)
{
m_HeadNode = m_HeadNode.m_NextNode;
}
if(m_HeadNode != null)
{
Node previous = m_HeadNode;
Node current = m_HeadNode.m_NextNode;
while (current != null)
{
if (current.data == data)
{
// If we're removing the last entry in the list, current.Next
// will be null. That's OK, because setting previous.Next to
// null is the proper way to set the end of the list.
previous.m_NextNode = current.m_NextNode;
// If we remove the current node, then we don't need to move
// forward in the list. The reference to previous.Next, below,
// will now point one element forward than it did before.
}
else
{
// Only move forward in the list if we actually need to,
// if we didn't remove an item.
previous = current;
}
current = previous.m_NextNode;
}
}
}
只有一个局部变量。
您的代码中有一个bug,假设您有一个包含3个元素的列表,其中data=5,并且您想要删除5个元素,那么您的代码将头部存储在aCurrentNode中并启动循环。在这里,条件为真,因此您可以将头部移动到下一个。但是aCurrentNode没有更新,因此在下一次迭代中,它指向上一个头部,aCurrentNode.m_NextNod将是您当前的头部,因此您陷入了一个永无止境的循环
public void Remove(int data)
{
for(var cur = new Node {Next = Head}; cur.Next != null; cur = cur.Next)
{
if (cur.Next.Data != data) continue;
if (cur.Next == Head)
Head = Head.Next;
else
cur.Next = cur.Next.Next;
}
}
使循环更简单的一个技巧是从指向头部的假节点开始。通过这种方式,您不需要以不同的方式放置If来检查头部,但是您需要If来设置头部。另一个技巧是检查下一个节点的数据。这样,您就不需要保留以前的节点。publicslement-Remove(int-index)
public bool RemoveNode(int data) {
Node prev = null;
for (Node node = head; node != null; node = node.next) {
if (node.data == data) {
if (prev == null) head = node.next;
else prev.next = node.next;
return true;
}
prev = node;
}
return false;
}
{
SLElement prev=_根;
if(prev==null)返回null;
SLElement curr=\u root.\u next;
对于(int i=1;i
这将删除具有特定索引的元素,而不是具有特定值的元素,从而使操作变得非常简单。请按照下面的说明。下面是从单个链接列表中删除项的代码段
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;
}
}
你的代码块真的被破坏了,但这会有帮助吗?你说的“更好”是什么意思?可读性更强、性能更好、代码更少等等?这只是一个编程练习吗?C#一个内置的类型安全双链表。关于其他部分,我使用了三个节点来删除数据;首先我记得上一个节点,然后从上一个节点我从当前节点中获取当前节点我得到下一个节点,一旦数据匹配,我移除当前节点并在上一个节点和当前节点之间建立链接,有没有更好的方法来实现相同的目标你真的不需要返回,他的实现将删除所有出现的数据。
public SLElement Remove(int index)
{
SLElement prev = _root;
if (prev == null) return null;
SLElement curr = _root._next;
for (int i = 1; i < index; i++)
{
if (curr == null) return null;
prev = curr;
curr = curr._next;
}
prev._next = curr._next;
curr._next = null;
return curr;
}
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;
}
}