复制链表,链表中的每个节点有两个链域,一个是next链,另个是random链(可以指向链表节点的任何节点包括null)
节点结构:
class RandomListNode {
public int label;
public RandomListNode next,random;
Random rand = new Random(1);
public RandomListNode(int x){
this.label = x;
}
}
复制一个链表简单,甚或深复制一个链表,都差不多。但此题中关键包含random域
先上用一般方法写的复制:
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) {
return head;
}
//复制next链
RandomListNode cur = head;
while (cur != null) {
RandomListNode newNode = new RandomListNode(cur.label);
newNode.next = cur.next;
cur.next = newNode;
cur = newNode.next;
}
//复制random链
cur = head;
while (cur != null) {
if (cur.random != null) {
cur.next.random = cur.random.next;
}
cur = cur.next;
}
//将链表断成两个链
cur = head.next;
RandomListNode newHead = cur;
RandomListNode old = head;
while (old != null) {
if (old.next != null) {
old.next = old.next.next;
}
cur = cur.next;
old = old.next;
}
return newHead;
}
这个random域应该怎么初始化(怎么让链表的random域可以指向任意的节点)?
将RandomListNode都存入数组arr[],生成随机数rand,以数组长度作为随机数nextInt()方法的参数随机选择index,然后令每个节点的random域指向arr[index]
例如:
RandomListNode n1 = new RandomListNode(8);
RandomListNode n2 = new RandomListNode(9);
RandomListNode n3 = new RandomListNode(0);
RandomListNode n4 = new RandomListNode(5);
RandomListNode n5 = new RandomListNode(1);
RandomListNode n6 = new RandomListNode(0);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
RandomListNode[] randomList = { n1, n2, n3, n4, n5, n6 };
RandomListNode head = n1;
while(head!=null){
head.random = randomList[new Random().nextInt(randomList.length)];
head = head.next;
}
到此,RandomList完整,copyRandomList完整。
想想能不能用实现Clonable接口实现这个问题?
以下方法不正确,但是我觉得如果能这样进行链表深复制,代码要比上面简单多了,同样也希望能看到大神帮助修改达到期望的目的。
只要链表节点可以深复制,那么只需对链表头结点深复制即可达到对链表的每个节点的深复制。
首先对RandomListNode结构进行改写(改写成可深复制的类):
class RandomListNode implements Cloneable{
public int label;
public RandomListNode next,random;
Random rand = new Random(1);
public RandomListNode(int x){
this.label = x;
}
public RandomListNode clone(){
RandomListNode o = null;
try{
o = (RandomListNode) super.clone();
}catch(CloneNotSupportedException e){
System.out.print(e.toString());
}
o.next = this.next.clone();
o.random = this.random.clone();
return o;
}
}
那么就可以进行链表的节点深复制了,并且代码很简洁,不会再像方法一中那样麻烦的操作链表了:
public RandomListNode copyRandomListClone(RandomListNode head) {
RandomListNode newHead = null;
<span style="white-space:pre"> </span>newHead = head.clone();//这块会出现问题,当链表深复制到尾节点时,会有nullpointer错误,复制终止
return newHead;
}
希望看到的能给与指教。。。