我一直在研究一些代码来实现java中的(edit:单向)链表。我的主要问题是在查找和删除节点时,即使用查找(数据)告诉用户列表中是否存在节点;删除(数据)实际上会在找到节点后从列表中删除节点(如果找不到节点则不执行任何操作)。查找(数据)和删除(数据)使用相同的if-else逻辑,所以现在我只是将Find方法中的代码复制到delete方法中,在delete方法中使用适当的指针来"跳过&# 34;已删除的节点。
我想知道是否有更有效的方法。我想在删除块中使用布尔值,例如:
public void Delete(data)
{
if Find(data)
{
//code to delete node
}
}
但由于当前节点可能位于头部,尾部或中间的某个位置,因此您仍需要使用循环逻辑来检查您的位置,以便设置适当的引用。例如,如果用户想要删除尾部的节点,则前一节点的下一个节点将被设置为空。但是,在中间,你必须运行一个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;
}
}
上面的代码块处理这两种情况。
以下代码块是我的查找(数据)方法:
public void Find(int data)
{
Node node = head;
if (head == null)
{
System.out.println("No nodes found. ");
}
else if (node.NextNode==null)
{
if (node.data == data)
{
System.out.println( data + " was found in the list.");
}
else
{
System.out.println("That value was not found in the list.");
}
}
else
{
while (node.NextNode !=null)
{
if (node.data == data)
{
System.out.println(data + " was found in the list.");
break;
}
else if (node.NextNode.NextNode == null && node.NextNode.data == data)
{
System.out.println(data + " was found in the list.");
break;
}
else
{
node = node.NextNode;
}
if (node.NextNode == null && node.data != data)
{
System.out.println(data + " was not found in the list.");
break;
}
}
}
}
如果问题不清楚:有没有办法在删除块中使用我的Find(数据)方法,并取出所有逻辑?
感谢您的指导。我真的很感激!
答案 0 :(得分:0)
由于您的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()方法中调用此方法。
void Find(int data) {
// Code to handle head & tail conditions
Node prevNode = getPreviousNode(data);
if (prevNode != null) {
System.out.println("Found");
}
...
}
void Delete(int data) {
// Code to handle head & tail conditions
Node prevNode = getPreviousNode(data);
if (prevNode != null) {
Node node = prevNode.nextNode;
prevNode.nextNode = node.nextNode;
node.nextNode = null;
System.out.println("Found & Deleted");
}
...
}
回答你的评论:
只写“prevNode.nextNode = prevNode.NextNode.NextNode”是不够的。
考虑使用LinkedList:
A [data = 1 | nextNode = b] - > B [data = 4 | nextNode = c] - > C [数据= 55 | nextNode = null]
其中,
A,B,C:节点
a,b,c:分别参考节点A,B和C.
B:要删除的节点
现在考虑删除节点的代码:
Node prevNode = getPreviousNode(data);
prevNode = a; //“a”是对getPreviousNode(4)返回的节点A的引用
if (prevNode != null)
node = prevNode.nextNode;
node = b; // prevNode.nextNode是'b'
prevNode.nextNode = node.nextNode;
prev.NextNode = c; // node.nextNode是'c'
现在LinkedList是:
A [data = 1 | nextNode = c] B [data = 4 | nextNode = c] - > C [数据= 55 | nextNode = null]
现在,节点A将节点C的引用作为nextNode。因此节点B与LinkedList断开链接 但是没有完全从LinkedList中删除,因为节点B仍然具有Node C的引用 作为NextNode。因此,您必须删除此引用才能从LinkedList中完全删除Node B.
所以下面的陈述是必要的
node.nextNode = null;
现在LinkedList是:
A [data = 1 | nextNode = c] - > C [数据= 55 | nextNode = null]
B [data = 4 |从LinkedList中删除nextNode = null]。
答案 1 :(得分:0)
您可以像@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
节点,它会比这更长,也更复杂。
答案 2 :(得分:0)
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( ) );
}
}
}