【剑指offer】复杂链表的复制

题目:

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),实现链表的复制。


分析:

首先想到的是先将链表的下一个节点链路复制出一条链表,再从头开始将链表的任意节点指针复制,问题在于任意节点的指针可以指向任意位置,每个节点都要从头查找。

由于链表的顺序性,可以将复制链表复制在原链表内部,最后拆分为两个单独的复杂链表即可。这样任意节点的指针就可以根据原链表节点之间找到,无需遍历查找。


实现:

<span style="font-family:Microsoft YaHei;font-size:14px;">public RandomListNode Clone(RandomListNode pHead) {
	if (pHead == null) {
		return null;
	}
	clone(pHead);
	random(pHead);
	return copylist(pHead);
}

public void clone(RandomListNode pHead) {
	RandomListNode node = pHead;
	while (node != null) {
		// 复制一个当前结点,注意需要新建出结点
		RandomListNode clone = new RandomListNode(node.label);
		// 将复制结点插入当前结点后面
		clone.next = node.next;
		node.next = clone;
		// 移动当前节点位置,继续循环
		node = clone.next;
	}
}

public void random(RandomListNode pHead) {
	// 设置两个指向当前结点和复制结点的“指针”
	RandomListNode node = pHead;
	RandomListNode clone = null;
	while (node != null) {
		// if (node.next != null) {
		clone = node.next;
		// }
		// 根据当前结点的random设置复制结点的random
		if (node.random != null) {
			clone.random = node.random.next;
		}
		node = clone.next;
	}
}

// 抽出一个拆分链表的函数:将奇偶项分别拆开为两个链表
public RandomListNode copylist(RandomListNode pHead) {
	RandomListNode plist = pHead;
	// 记录复制链表的头结点,防止覆盖
	RandomListNode clonehead = plist.next;
	RandomListNode clonenode = plist.next;
	plist.next = clonenode.next;
	plist = plist.next;
	while (plist != null) {
		clonenode.next = plist.next;
		clonenode = clonenode.next;
		plist.next = clonenode.next;
		plist = plist.next;
	}
	return clonehead;
}

public static void printList(RandomListNode head) {
	while (head != null) {
		System.out.print(head.label + "->");
		head = head.next;
	}
	System.out.println("null");
}</span>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值