Java linkedlist-如何复制数据?
我试图编写一个函数,将双链接列表中的“n”个节点从前面移动到后面: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
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,但是你怎么能考虑排除一些操作来测量复杂性?(我的意思是,是的,它会更有效率,但不会改变复杂性。)