单链表:remove方法
本文关键字:remove 方法 链表 单链表 | 更新日期: 2023-09-27 17:48:58
我正在用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
{
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();
}
}
我会将"if removing the 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;
}
}
}
您有一行不需要:
m_HeadNode = null;
m_HeadNode = aCurrentNode.m_NextNode;
在将m_HeadNode设置为其他值之前,不需要将其设置为null。
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;
}
public void RemoveData(int data)
{
if(null == m_HeadNode) return;
if(m_HeadNode.data == data)
{
// remove first node
}
else
{
Node current = m_HeadNode;
while((null != current.m_NextNode) && (current.m_NextNode.data != data))
current = current.m_NextNode;
if(null != current.m_NextNode)
{
// do remove node (since this sounds like homework, I'll leave that to you)
}
}
}
只有一个局部变量
你的代码中有一个错误,假设你有一个列表,其中有3个元素,数据=5,你想删除5,你的代码将头部存储在aCurrentNode中并开始循环。在那里,条件是真的,所以你把头移到下一个。但是aCurrentNode没有更新,所以在下一次迭代中,它指向上一个Head,而aCurrentNode.m_NextNod将是您当前的Head,因此您陷入了一个永无止境的循环!
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;
}
}
让循环更简单的一个技巧是从一个指向head的假节点开始。这样,你就不需要放置一个If来以不同的方式检查头部,但你需要一个If来设置头部。另一个技巧是检查下一个节点的数据。这样就不需要保留以前的节点。
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;
}
}