我正在编写自己的链接列表实现,如下所示,当我尝试执行操作' deleteElementFromHead'链接列表,我很好奇我所做的是否足够? 从头部删除元素的方法如下,
public void deleteAtHead()
{
Node secondNode = this.head.next;
this.head = secondNode;
count--;
}
我怀疑在交换指针以删除头部的元素时,旧的head元素仍然在内存中,垃圾收集器可能收集也可能不收集。我是否需要将已删除的元素设置为null,或者需要在上述方法中添加一些其他代码以避免内存泄漏。
链表的完整代码如下,
package com.nobalg.Linkedist;
public class Node implements Operations {
int data;
Node next,head,tail;
int count = 1;
public Node(int data)
{
this.data = data;
this.head=this;
this.tail = this;
}
/**********This method takes O(n) time************/
public void addNode(int nodeData)
{
Node node = new Node(nodeData);
Node temp = this;
while(temp.next!=null){
temp = temp.next;
}
temp.next = node;
count++;
}
/******This operation takes O(1) time********/
public void addAtTail(int nodeData)
{
Node node = new Node(nodeData);
tail.next = node;
tail = tail.next;
count++;
}
/********This operation takes O(1) time**************/
public void addAtHead(int nodeData)
{
Node node = new Node(nodeData);
node.next = head;
this.head = node;
count++;
}
/************This operation takes O(n) time****************/
public void addAtIndex(int index,int nodeData)
{
if(index < 0 || index >count)
{
throw new IllegalStateException();
}
Node node = new Node(nodeData);
Node tempLast = this.head;
Node tempCurrent = this.head;
int locCount = 0;
while(locCount!=index){
tempLast = tempCurrent;
tempCurrent = tempCurrent.next;
locCount++;
}
node.next = tempCurrent;
if(index == 0)this.head = node;
else tempLast.next = node;
count++;
}
/**********This operation takes O(n) time in case of singly linked list*************/
public void deleteAtTail()
{
Node temp = this.head;
Node locLastNode = null;
while(temp.next!=null)
{
locLastNode = temp;
temp = temp.next;
}
this.tail = locLastNode;
locLastNode.next = null;
count--;
}
public void deleteAtHead()
{
Node secondNode = this.head.next;
this.head = secondNode;
count--;
}
public void deleteAtIndex()
{
//implementation pending
}
public int size()
{
return count;
}
public void display()
{
Node temp = this.head;
for(int i = 0 ; i < count; i++)
{
System.out.println(temp.data);
temp = temp.next;
}
}
}
答案 0 :(得分:1)
以下代码
public void deleteAtHead()
{
Node secondNode = this.head.next;
this.head = secondNode;
count--;
}
有一些边缘情况丢失,就像它会抛出NPE,当LL为空而另一个是它只有1个节点时。无论如何,你的问题如下: -
我怀疑在交换指针时删除元素 头部,旧头元素仍在记忆中,可能会也可能不会 被垃圾收集者收集。我是否需要设置已删除 元素为null,或者需要在上面添加一些其他代码 避免内存泄漏的方法。
所以是的,在这种情况下,旧的head元素仍然会在内存中,但它不会指向你的LL的头部,所以你不会得到错误的结果。 GC运行一段时间后,无论你是否将它设置为 NULL ,它都会被它收集。
详细了解在此SO答案中明确指定 NULL 时会发生什么: - Does assigning objects to null in Java impact garbage collection?
答案 1 :(得分:0)
我猜你错过了尾部和头部指向同一节点的情况之一。假设只有一个元素,并且您调用deleteAtHead()
。在这种情况下,Node
有两个引用,一个是head
,另一个是tail
,您只是取消引用(this.head = secondNode; count--;
)头节点,{{{ 1}}节点。是不是仍然引用第一个节点。这是你的程序中断。你应该考虑这个案子。如果任何对象没有引用,那么您不需要担心该对象,GC将收集/释放该对象。但是您需要确保正确地取消引用所有这些对象。
答案 2 :(得分:0)
垃圾收集器自动在JVM的后台运行。 如果资源没有分配给任何变量或者没有给出任何引用,它将被垃圾收集器清理。
以下是在某个位置删除的代码。
Node deleteAtIndex(Node head, int position) {
Node temp = head;
if(head == null)
return null;
else if(position == 0){
head=head.next;
}
else{
int currentIndex = 0;
while(temp != null && currentIndex <= position-2){
currentIndex++;
temp=temp.next;
}
Node temp2 = temp.next.next;
temp.next=temp2;
}
return head;
}
答案 3 :(得分:0)
旧的头部元素仍然在内存中,可能会也可能不会 由垃圾收集器收集。我是否需要设置已删除 元素为null,或者需要在上面添加一些其他代码 避免内存泄漏的方法
所以,你需要理解这一点,JVM负责GC,你不需要那么多的控制。此外,设置null
并不意味着您可以立即获得分配的内存。
例如:
Object obj = new Object ();
在JVM中创建一个对象并分配\ reserve内存。现在,设置obj=null
表示obj
具有null
引用,但分配的内存仍然存在,没有引用(并且符合GC条件)。
答案 4 :(得分:0)
交换指针
Node secondNode = this.head.next;
this.head = secondNode;
count--;
在上面的代码片段中,旧元素仍然保留在内存中,这就是悬空指针的情况。 对于您的问题如何从堆中释放内存,请参阅this question
您也可以在一行this.head = this.head.next
中编写此内容,JVM很可能会处理垃圾收集......
然而,坚持你写的两行。这是一种更好的方法。
希望这会有所帮助:)