递归复制链接列表(Java)

时间:2015-05-21 08:19:22

标签: java recursion

漫长的一夜结束,我遇到了递归复制链表的问题,我能用一个简单的迭代方法做到这一点,但是当我尝试设置它时遇到堆栈溢出错误的问题与递归。然而,这在概念上对我有意义。任何人都可以引导我朝着正确的方向前进吗?这就是我到目前为止所做的:

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());
    }
}

4 个答案:

答案 0 :(得分:3)

每次进入方法时,都会创建一个新的LinkedList。

我怀疑你想在方法之外实例化它,传入它并每次都添加它。

答案 1 :(得分:0)

我认为它可以这么简单:

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);
            }

首先创建一个空的新链表,它将包含该副本,然后逐个节点地逐个复制到其中。你也不能像这样传递一个累加器:

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;
                }

但这会颠倒列表中节点的顺序。

以下是递归复制和递归反转的完整工作示例:

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;
            }
        }
    }
}

答案 2 :(得分:0)

如果你想使用递归方法来复制你的链表,我想你应该首先在另一个调用createCopyRecursive()的方法中初始化copyList。

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

答案 3 :(得分:0)

您可以担心头节点,而不是传递整个链接列表对象。

调用递归方法copy()

Node<Integer> copiedHead = copy(head);    

递归方法复制,接受头节点并返回复制的头节点。

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