2011-04-14 81 views
4

在Java中,如何使用已有的clear()方法删除链接列表中的所有元素而不使用?这项练习的灵感来自于电话采访中收到的问题。Java:删除链接列表中的所有元素

我可以用C

执行此操作
void DeleteAllElement(ListElement **head) { 
    ListElement *deleteMe = *head; 
    while(deleteMe) { 
     ListElement *next = deleteMe->next; 
     delete deleteMe; 
     deleteMe = next; 
    } 
    *head = NULL; 
} 

谢谢

+0

缩进每行4个空格以获得自动“代码”块。有一个工具可以做到这一点:选择线条并点击'{}'图标。 – 2011-04-14 04:35:25

+0

删除我的答案,但真的,为什么不使用clear()。这就是它的目的。为什么重新发明轮子? – squawknull 2011-04-14 04:35:41

+0

因为我在电话采访中被问到 – SuperMan 2011-04-14 04:36:19

回答

11

Java提供了自动垃圾收集,所以你只需要设置元首参考空:

myList.headNode = null;

所以,我们假设我们有LinkedList类,它也有resetList函数...

public class LinkedList{ 
    private Node head; 
    public Node find(Key k){ ... } 
    public void add(Node n){ ... } 
    ... 
    public void reset(){ head = null;} 
    public static void reset(LinkedList l){l.reset();} 
} 

如果我们没有将head节点设置为私有,我们可以简单地执行我发布的第一个代码片段。

+0

我已经写过我的java代码,可以用它来表达吗? – SuperMan 2011-04-14 04:57:27

+1

您需要将列表的引用设置为空,而不是传递的引用。 'DeleteAllElement'应该接受列表,而不是头节点,并将列表的头部设置为'null'。否则,实际列表将保留其对现有头部的参考。 – bdares 2011-04-14 05:02:59

+0

注意在你的答案中的代码形式的措辞,所以我可以接受它? – SuperMan 2011-04-14 05:05:27

1
for(i=0;i<linkedlist.size;i++){ 
linkedlist.removeFirst(); 
} 

或看到this example

7

如果你正在谈论的java.util.LinkedList一个实例:

while (!linkedlist.isEmpty()) { 
     linkedlist.removeFirst(); 
    } 

如果你正在谈论任何java.util.List的一个实例:

while (!list.isEmpty()) { 
     list.remove(0); 
    } 

轴承记住remove是一个opti正常运行。但是,根据清单的实施情况,这可能非常有效。对于ArrayList这会更好:

while (!list.isEmpty()) { 
     list.remove(list.size() - 1); 
    } 

另一种方法是遍历列表,每个元素......还有一个可选操作上调用Iterator.remove()。 (但是,再次说明,对于某些列表实现来说这可能是非常低效的)。

如果您正在讨论自定义链表类,那么答案取决于您声明列表类的内部数据结构的方式。


我怀疑,如果面试官提到的clear()方法,他们期待在标准的Java集合框架...不是一个自定义的链表类的上下文答案。

1

阅读实际的代码很有用。我建议你看看。

对于单向链表,您可以仅做为@bdares,当您查看java.util.LinkedList的实际代码(这是大多数开发人员使用的代码)时,建议的答案很不相同。

public void clear() { 
    Entry<E> e = header.next; 
    while (e != header) { 
     Entry<E> next = e.next; 
     e.next = e.previous = null; 
     e.element = null; 
     e = next; 
    } 
    header.next = header.previous = header; 
    size = 0; 
    modCount++; 
} 

首先要注意的是;这是用于前向和后向遍历的双向链表,并且它极力清除所有参考。不知道为什么这样做是值得尊重的,因为GC会以任何方式清除它,并且modCount会在另一个线程中发现任何更改。实际上它应该首先执行modCount。

为了比较,这里是ArrayList.clear();

public void clear() { 
    modCount++; 

    // Let gc do its work 
    for (int i = 0; i < size; i++) 
     elementData[i] = null; 

    size = 0; 
}