对RandomList进行深复制

本文介绍了一种含有random域的复杂链表复制方法,通过在原链表中插入新节点并调整random指针来完成复制过程。此外,还探讨了使用随机数初始化random域的方法以及尝试实现深复制的思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

复制链表,链表中的每个节点有两个链域,一个是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;
	}
希望看到的能给与指教。。。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值