简体   繁体   English

递归复制链接列表(Java)

[英]Copying Linked List Recursively (Java)

End of a long night and I'm having trouble with copying a linked list recursively, I was able to do so with a simple iterative method, but I am having trouble with a stack overflow error when I try to set it up with recursion. 一个漫长的夜晚结束了,我在递归地复制链表时遇到了麻烦,我能够使用一种简单的迭代方法来做到这一点,但是当我尝试通过递归设置它时,却遇到了堆栈溢出错误。 Yet, this makes sense to me conceptually. 但是,从概念上讲,这对我来说是有意义的。 Can anyone steer me in the right direction? 谁能引导我正确的方向? This is what I have so far: 这是我到目前为止的内容:

public LinkedList<E> createCopyRecursive(Node<E> aNode) {
    LinkedList<E> copyList = new LinkedList<E>();
    copyList.myStart = myStart;

    if (copyList.size() == 0) {
        aNode = myStart.getLink();
    }

    if (aNode.getLink() == null) {
        return copyList;
    }
    else {
        copyList.add(aNode.getValue());
        return createCopyRecursive(aNode.getLink());
    }
}

You're creating a new LinkedList every time you recurse into the method. 每次递归到该方法时,您都在创建一个新的LinkedList。

I suspect you want to instantiate it outside the method, pass it in and add to it each time through. 我怀疑您想在方法之外实例化它,将其传递并每次添加。

I think it can be as simple as this: 我认为它可以像这样简单:

private LinkedList<E> copyRecursive(final Node<E> node, final LinkedList<E> accumulator) {
                if (node == null) {
                    // all nodes traversed, return the result.
                    return accumulator;
                }
                // add current node to the copy list that is under construction.
                accumulator.add(node.getElement());
                // recursive call to copy the rest of the nodes to the copy list and return it when finished.
                return copyRecursive(node.getNext(), accumulator);
            }

First create an empty new linked list, which will contain the copy and then copy node by node into it recursively. 首先创建一个空的新链表,其中将包含副本,然后将每个节点递归复制到该列表中。 You could also not pass an accumulator to it like this: 您也不能像这样将累加器传递给它:

private LinkedList<E> copyRecursive(final Node<E> node) {
                    if (node == null) {
                        return new LinkedList<>();
                    }
                    final LinkedList<E> accumulator = copyRecursive(node.getNext());
                    accumulator.add(node.getElement());
                    return accumulator;
                }

But that will reverse the order of the nodes in the list. 但这将颠倒列表中节点的顺序。

Here is a fully working example with recursive copy and recursive reverse: 这是一个具有递归复制和递归反向的完全有效的示例:

public class RecursiveCopyTest {
    public static void main(String[] args) {
        final LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("first");
        linkedList.add("next");
        linkedList.add("last");
        System.out.println(linkedList);
        System.out.println(linkedList.copyRecursive());
        System.out.println(linkedList.reverse());
   }

private static class LinkedList<E> {

    private Node<E> first;

    public LinkedList() {
        first = null;
    }

    public LinkedList<E> copyRecursive() {
        return copyRecursive(first, new LinkedList<E>());
    }

    public LinkedList<E> reverse() {
        return reverse(first);
    }

    public void add(E element) {
        final Node<E> node = new Node<>(element);
        if (first == null) {
            first = node;
        } else {
            Node<E> current = first;
            while (current.getNext() != null) {
                current = current.getNext();
            }
            current.setNext(node);
        }

    }

    private LinkedList<E> reverse(final Node<E> node) {
        if (node == null) {
            return new LinkedList<>();
        }
        final LinkedList<E> accumulator = reverse(node.getNext());
        accumulator.add(node.getElement());
        return accumulator;
    }

    private LinkedList<E> copyRecursive(final Node<E> node, final LinkedList<E> accumulator) {
            if (node == null) {
                return accumulator;
            }
            accumulator.add(node.getElement());
            return copyRecursive(node.getNext(), accumulator);
        }

        @Override
        public String toString() {
            final StringBuilder stringBuilder = new StringBuilder();
            Node current = first;
            while (current != null) {
                stringBuilder.append(current.getElement().toString()).
                        append(" -> ");
                current = current.getNext();
            }
            stringBuilder.append(" _ ");
            return stringBuilder.toString();
        }

        private static final class Node<E> {
            private final E element;
            private Node<E> next;

            public Node(final E element) {
                this.element = element;
            }

            public E getElement() {
                return element;
            }

            public void setNext(final Node<E> next) {
                this.next = next;
            }

            public Node<E> getNext() {
                return next;
            }
        }
    }
}

If you want to use a recursive method to copy your linked list, I think you should first initialize copyList in another mehod that calls createCopyRecursive(). 如果要使用递归方法复制链接列表,我认为您应该首先在另一个调用createCopyRecursive()的方法中初始化copyList。

createCopy(Node<E> aNode) {
   LinkedList<E> copyList = new LinkedList<E>();
   createCopyRecursive(aNode, copyList) {
      ....
   }
}

Rather than passing around whole linkedlist object you can just worry about head node. 您不必担心整个链表对象,而只需担心头节点。

Call to recursive method copy() 调用递归方法copy()

Node<Integer> copiedHead = copy(head);    

Recursive method copy, accepts the head node and returns the copied head node. 递归方法复制,接受头节点并返回复制的头节点。

private static Node<Integer> copy(Node<Integer> head) {
    if(head == null){
        return null;
    }   
    return new Node<>(head.getData(), copy(head.getNext()));            
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM