在Java中实现链表(查找/删除节点)
我一直在编写一些代码,用java实现(编辑:单向)链表。我的主要问题是查找和删除节点,也就是说,使用Find(数据)告诉用户列表中是否存在节点;Delete(data)实际上是在找到节点后将其从列表中删除(或者如果找不到节点,则不执行任何操作)。Find(data)和Delete(data)使用相同的if-else逻辑,所以现在我只是将代码从Find方法复制到Delete方法中,Delete方法中有适当的指针来“跳过”已删除的节点 我想知道是否有更有效的方法。我曾想过在删除块中使用布尔值,例如:在Java中实现链表(查找/删除节点),java,linked-list,Java,Linked List,我一直在编写一些代码,用java实现(编辑:单向)链表。我的主要问题是查找和删除节点,也就是说,使用Find(数据)告诉用户列表中是否存在节点;Delete(data)实际上是在找到节点后将其从列表中删除(或者如果找不到节点,则不执行任何操作)。Find(data)和Delete(data)使用相同的if-else逻辑,所以现在我只是将代码从Find方法复制到Delete方法中,Delete方法中有适当的指针来“跳过”已删除的节点 我想知道是否有更有效的方法。我曾想过在删除块中使用布尔值,例如:
public void Delete(data)
{
if Find(data)
{
//code to delete node
}
}
但由于当前节点可能位于头部、尾部或中间的某个地方,所以您仍然需要具有循环逻辑来检查您在何处,以便可以设置适当的引用。例如,如果用户希望删除尾部的节点,则前一个节点的下一个节点将设置为null。但是,在中间,您必须运行一个while循环来遍历列表,即
。while (iter.NextNode !=null)
{
if (iter.NextNode.data == data)
{
iter.NextNode = iter.NextNode.NextNode;
System.out.println(data + " was found in the list and removed"
break;
}
else if (iter.NextNode.NextNode == null && iter.NextNode.data == data)
{//this is kinda weird. I couldn't use an else block, because either
//the code would never exit the loop, or it would keep running
iter.NextNode = null;
System.out.println(data + " was found in the list and removed. ");
break;
}
iter = iter.NextNode;
if (node.NextNode == null && node.data != data)
{//i guess I could have just put this if statement inside
//the else block
System.out.println(data + " was not found in the list.");
break;
}
}
上面的代码块处理这两种情况
下面的代码块是我的查找(数据)方法:
}
如果问题不清楚:是否有一种方法可以在delete块中使用Find(data)方法,并删除所有逻辑
谢谢你的指导。我真的很感激 由于Find()方法不返回任何内容,因此不能在Delete()方法中使用它。
要集中Find()和Delete()的代码,请创建另一个私有方法getPreviousNode(int data),该方法返回所需节点的前一个节点
private Node getPreviousNode(int data) {
Node iter = head;
while (iter.NextNode != null) {
if (iter.NextNode.data == data) {
return iter;
}
iter.nextNode = iter.nextNode.nextNode;
}
return null;
}
在Find()和Delete()方法中调用此方法
回答您的评论:
仅写“prevNode.nextNode=prevNode.nextNode.nextNode”是不够的 考虑以下链接列表:
A[data=1 | nextNode=b]->b[data=4 | nextNode=c]->c[data=55 | nextNode=null] 其中,
A、 B,C:节点
a、 b、c:分别引用节点a、b和c。
B:要删除的节点
现在考虑删除节点的代码:
Node prevNode = getPreviousNode(data);
prevNode=a;//“a”是对getPreviousNode(4)返回的节点a的引用
node=b;//prevNode.nextNode为“b”
prev.NextNode=c;//node.nextNode是“c”
现在LinkedList是:
A[data=1 | nextNode=c]B[data=4 | nextNode=c]->c[data=55 | nextNode=null]
现在节点A有一个节点C的引用作为下一个节点。因此节点B与LinkedList解除链接
但没有从LinkedList中完全删除,因为节点B仍然具有节点C的引用
作为下一个节点。因此,必须删除此引用才能从LinkedList中完全删除节点B
所以下面的陈述是必要的
node.nextNode = null;
现在LinkedList是:
A[data=1 | nextNode=c]->c[data=55 | nextNode=null]B[data=4 | nextNode=null]已从LinkedList中删除
您可以按照@SanjayChavan的建议共享
findPrevious
,但当您练习编写链表代码时,您会发现它已经很干净了,共享findPrevious
并不能让它变得更好:
boolean Delete(int data)
{
Node prev = null, node = null;
for (node = head; node!=null; node=(prev=node).nextNode)
{
if (node.data == data)
{
if (prev!=null)
prev.nextNode = node.nextNode;
else
head = node.nextNode;
node.nextNode = null;
return true;
}
}
return false;
}
Node Find(int data)
{
for (Node node = head; node != null; node = node.nextNode)
{
if (node.data==data)
return node;
}
return null;
}
一旦Sanjay的代码被修复,这样它就可以找到并删除
head
节点,它将比这更长更复杂。查找和删除方法背后的逻辑是不同的。在“删除”中,需要指向要删除的节点之前的指针。但是,find方法可能只返回已找到的节点。为什么find(int data)
方法不返回任何内容?如果它不返回对找到的节点的引用
?@JonnyHenly即使他这样做,也不一定有助于删除,因为假设他的列表是单向的,他也需要上一个节点。@TimBiegeleisen你是对的,我假设是双链接列表。但是,OP的Find(int data)
,如果是公共的,应该至少返回一个布尔值
,如果不是节点
…很抱歉,我发布的文本和代码不一致。当我说“上一个”节点时,我实际上是指当前节点,因为我可以通过说node.next=node.next.next来删除node.next;在上面,我说的是boolean,但我在尝试实现它时遇到了问题,所以在发布问题时,我将Find(data)的返回类型更改为void。再一次,很抱歉造成混乱。此外,是的,这是一个单向链表,上面已经对此进行了澄清。我不能说:prevNode.nextNode=prevNode.nextNode.nextNode?在注释中使用您的语句,您正在将前一个节点(prevNode)的引用从所需节点(要删除的节点)更改为下一个节点。但所需节点仍具有下一个节点的引用。因此它仍然与您的LinkedList连接。所以需要语句“node.nextNode=null”才能从列表中完全删除节点。在这个语句之后,您可以使“node=null”,这样所有对所需节点的引用都将被删除。另外,getPrevious
修改iter.nextNode
,我相信您不打算这样做
public static ListNode search( List list, int target )
{
ListNode cursor = list.getFirst( );
while( cursor != null )
{
if( cursor.getInfo( ) == target )
return cursor;
cursor = cursor.getLink( );
}
return cursor;
}
public void remove( int element )
{
ListNode cursor;
ListNode target = search( this, element );
if( isEmpty( ) )
System.out.println( "There are no elements in this list." );
if( target == null )
System.out.println( element+" is not in this list." );
else
{
if( head.getInfo( ) == element )
{
if( head.getLink( ) == null )
head = null;
else if( head == tail )
tail = null;
else
head = head.getLink( );
}
else if( tail.getInfo( ) == element )
{
for( cursor = head; cursor.getLink( ).getInfo( ) != element; cursor = cursor.getLink( ) )
{ }
cursor.setLink( null );
tail = cursor;
}
else
{
for( cursor = head; cursor.getLink( ).getInfo( ) != element; cursor = cursor.getLink( ) )
{ }
cursor.setLink( cursor.getLink( ).getLink( ) );
}
}
}
prevNode.nextNode = node.nextNode;
node.nextNode = null;
boolean Delete(int data)
{
Node prev = null, node = null;
for (node = head; node!=null; node=(prev=node).nextNode)
{
if (node.data == data)
{
if (prev!=null)
prev.nextNode = node.nextNode;
else
head = node.nextNode;
node.nextNode = null;
return true;
}
}
return false;
}
Node Find(int data)
{
for (Node node = head; node != null; node = node.nextNode)
{
if (node.data==data)
return node;
}
return null;
}
public static ListNode search( List list, int target )
{
ListNode cursor = list.getFirst( );
while( cursor != null )
{
if( cursor.getInfo( ) == target )
return cursor;
cursor = cursor.getLink( );
}
return cursor;
}
public void remove( int element )
{
ListNode cursor;
ListNode target = search( this, element );
if( isEmpty( ) )
System.out.println( "There are no elements in this list." );
if( target == null )
System.out.println( element+" is not in this list." );
else
{
if( head.getInfo( ) == element )
{
if( head.getLink( ) == null )
head = null;
else if( head == tail )
tail = null;
else
head = head.getLink( );
}
else if( tail.getInfo( ) == element )
{
for( cursor = head; cursor.getLink( ).getInfo( ) != element; cursor = cursor.getLink( ) )
{ }
cursor.setLink( null );
tail = cursor;
}
else
{
for( cursor = head; cursor.getLink( ).getInfo( ) != element; cursor = cursor.getLink( ) )
{ }
cursor.setLink( cursor.getLink( ).getLink( ) );
}
}
}