如何在自定义链接列表实现中避免不必要的递归?

时间:2014-10-16 15:39:48

标签: java algorithm recursion data-structures linked-list

我正在尝试在列表的末尾插入一个新节点,但它会不断递归。

我做错了什么?

public class Main {

    public static void main(String[] args) {
        run();
    }

    private static void run() {
        LinkedList list = new LinkedList();
        list.add("abc");
        list.add("def");
        list.add("ghi");
        list.add("jkl");
    }
}

add方法首先检查列表是否为空。

如果是这样,它会创建一个头节点。

否则,它会尝试查找列表的末尾并在那里插入新节点。

public class LinkedList<T> {

    Element head;
    Element terminator = new Element("TERMINATOR", true);

    public void add(T e) {
        Element node = new Element(e);
        if(head==null){
            head = node;
            head.setNext(terminator);
        }
        else {
            Element end = getEnd2();
            end.setNext(node);
        }
    }

    public Element getEnd2() {
        Element tmp;
        while((tmp = head.getNext())!=null){
            System.out.println("tmp:" + tmp.getValue());
        }
        return tmp;
    }

    public Element getEnd(){
        Element node = head;
        while(node!=null){
            System.out.println("node:" + node.getValue());
            node = head.getNext();
        }
        return node;
    }

    public Element getHead(){
        return head;
    }
}

public class Element<T>{
    T value;
    Element<T> next;

    boolean terminator;

    Element(T value){
        this.value = value;
    }

    Element(T value, boolean terminator){
        this.value = value;
        this.terminator = terminator;
    }

    public void setNext(Element<T> next) {
        this.next = next;
    }

    public Element getNext(){
        return next;
    }

    public T getValue(){
        return value;
    }

    public boolean isTerminator() {
        return terminator;
    }

    public void setTerminator(boolean terminator) {
        this.terminator = terminator;
    }

}

2 个答案:

答案 0 :(得分:0)

你的循环是无限的:

public Element getEnd(){
    Element node = head;
    while(node!=null){
        System.out.println("node:" + node.getValue());
        node = head.getNext(); // head.getNext() always returns the same value
    }
    return node;
}

如果将其更改为node = node.getNext(),则您的方法只会返回null。

如果您想要最后一个非空节点,请将其更改为:

public Element getEnd(){
    Element node = head;
    while(node.getNext()!=null){
        System.out.println("node:" + node.getValue());
        node = node.getNext();
    }
    return node;
}

getEnd2()具有相同的无限循环问题,但您无法修复它而不会与getEnd()完全相同,因为您无法对{{node进行分配1}}和同一语句中的空值检查(因为您只想在验证未向node分配空值后进行赋值)。

答案 1 :(得分:0)

它没有递归,它在线上无限循环:

while((tmp = head.getNext())!=null)

条件永远不会改变,所以如果head.getNext() != null,这将永远循环。