Java linkedlist-如何复制数据?

Java linkedlist-如何复制数据?,java,object,linked-list,Java,Object,Linked List,我试图编写一个函数,将双链接列表中的“n”个节点从前面移动到后面: public class PetList { protected class LinkNode { protected LinkNode next; protected LinkNode prev; protected Pet animal; // note that my data within a node is an object public Li

我试图编写一个函数,将双链接列表中的“n”个节点从前面移动到后面:

public class PetList {
    protected class LinkNode {
        protected LinkNode next;
        protected LinkNode prev;
        protected Pet animal; // note that my data within a node is an object

        public LinkNode() {
            next = prev = null;
        }
    }
    protected LinkNode first;
    protected LinkNode last;

    public PetList() {
        first = last = null;
    }
//...
//... other functions

public void Rotate(int n) {

}
现在我知道了如何在后面插入节点,例如:

public void insertRear(Pet giraffe) {
    LinkNode temp = new LinkNode();
    temp.animal = new Pet(giraffe);
    if(first == null) {
        first = last = temp;
        return;
    }
    temp.prev = last;
    last.next = temp;
    last = temp;
}
但在我的旋转函数中:

public void Rotate(int n)

我没有对象作为参数。也就是说,如何创建临时链接节点并复制第一个链接节点对象中的数据,然后将临时节点移到后面,即删除第一个节点?还是有其他更好的方法?谢谢你的帮助。

应该很简单。以下是如何将一个节点从头部移动到尾部:

public void moveHeadToTail() {
    if (first == null || last == null) {
        throw new IllegalStateException("can't do that on empty list");
    }
    // Detach the first node
    LinkNode temp = first;
    first = temp.next;
    first.previous = null;
    temp.next = null;

    // Put the tmp node at the end
    last.next = temp;
    temp.prev = last;
    last = temp;
}
然后,您可以将其拆分为更好的函数:
popHead
pushTail

public LinkNode popHead() {
    if (first == null) {
        throw new IllegalStateException("can't do that on empty list");
    }
    LinkNode temp = first;
    first = temp.next;
    first.previous = null;
    temp.next = null;
    return temp;
}

public void pushTail(LinkNode node) {
    if (last == null) {
        throw new IllegalStateException("can't do that on empty list");
    }
    last.next = node;
    node.prev = last;
    node.next = null;
    last = node;
}
从而使旋转更容易:

public void moveHeadToTail() {
    pushTail(popHead());
}

那么,使其适用于
n
的修改应该相当简单。

应该相当简单。以下是如何将一个节点从头部移动到尾部:

public void moveHeadToTail() {
    if (first == null || last == null) {
        throw new IllegalStateException("can't do that on empty list");
    }
    // Detach the first node
    LinkNode temp = first;
    first = temp.next;
    first.previous = null;
    temp.next = null;

    // Put the tmp node at the end
    last.next = temp;
    temp.prev = last;
    last = temp;
}
然后,您可以将其拆分为更好的函数:
popHead
pushTail

public LinkNode popHead() {
    if (first == null) {
        throw new IllegalStateException("can't do that on empty list");
    }
    LinkNode temp = first;
    first = temp.next;
    first.previous = null;
    temp.next = null;
    return temp;
}

public void pushTail(LinkNode node) {
    if (last == null) {
        throw new IllegalStateException("can't do that on empty list");
    }
    last.next = node;
    node.prev = last;
    node.next = null;
    last = node;
}
从而使旋转更容易:

public void moveHeadToTail() {
    pushTail(popHead());
}

然后,使其适用于
n
的修改应该是相当简单的。

我将从列表的开头切掉一段长度
n
节点,跟踪切掉列表中的第一个和最后一个节点。将
first
设置为截断子列表后面的节点,使其成为新的第一个节点。然后,通过提供子列表中最后一个旧节点和第一个节点之间的双向链接,将子列表追加到末尾。最后将
last
设置到子列表的末尾,我就完成了


将节点绘制为纸上的方框,将链接绘制为指向其他方框的箭头。擦除并绘制以可视化步骤。然后一切都会变得更清晰。

我会从列表的开头切掉一段长度
n
节点,跟踪切掉列表中的第一个和最后一个节点。将
first
设置为截断子列表后面的节点,使其成为新的第一个节点。然后,通过提供子列表中最后一个旧节点和第一个节点之间的双向链接,将子列表追加到末尾。最后将
last
设置到子列表的末尾,我就完成了


将节点绘制为纸上的方框,将链接绘制为指向其他方框的箭头。擦除并绘制以可视化步骤。那就更清楚了。

移动数据与复制数据不同为什么需要对象作为参数?您已经说过,您只想将列表中的第一项移到末尾。取下第一个节点,将其删除,将下一个节点标记为列表的新头,然后将第一个节点放在末尾。要扩展@njzk2 answer,请将
旋转
递归。为什么要创建新节点并复制数据?您只需移动现有节点,数据就会自动跟随。移动数据不同于复制数据为什么需要对象作为参数?您已经说过,您只想将列表中的第一项移到末尾。取下第一个节点,将其删除,将下一个节点标记为列表的新头,然后将第一个节点放在末尾。要扩展@njzk2 answer,请将
旋转
递归。为什么要创建新节点并复制数据?您只需移动现有节点,数据就会自动跟随。您可以通过一次移动整个块来执行O(1)中的更新(不计算遍历)。“(不计算遍历)”为什么不计算遍历?您仍然需要遍历n个元素才能找到截止点,但是你不需要更新每一个。@ SMOMOEL,但是你怎么能考虑排除一些操作来测量复杂性?(我的意思是,是的,它会更有效,但不会改变复杂性。)你可以通过移动整个块同时更新O(1)中的更新(不计数遍历)。为什么不计算遍历?你仍然需要遍历N个元素来找到截止点,但是你不需要更新每一个。@ SMOMOEL,但是你怎么能考虑排除一些操作来测量复杂性?(我的意思是,是的,它会更有效率,但不会改变复杂性。)