【笔试】43、复杂链表的复制

本文介绍了一种复杂链表的复制方法,该链表除了包含指向下一个节点的指针外,还包括指向链表中任意节点的兄弟指针。文章详细解释了如何通过三步法(节点复制、兄弟指针连接、重新连接)来完成复杂链表的复制。

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

我们的链表的节点类

/****************************************************************************************
 *题目:复杂链表的复制
 *		请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。在复杂链表中,
 *		每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者nullptr。
 *时间:2015年9月6日09:02:22
 *文件:ComplexListNode.java
 *作者:cutter_point
 ****************************************************************************************/
package bishi.Offer50.y2015.m09.d06;

public class ComplexListNode<T>
{
	public T m_nValue;
	public ComplexListNode<T> m_pNext;
	public ComplexListNode<T> m_pSibling;
	
	public ComplexListNode(T value)
	{
		this.m_nValue = value;
		m_pNext = m_pSibling = null;
	}
	
	/**
	 * 连接端点
	 * @param pNode
	 * @param pNext
	 * @param pSibling
	 */
	public static void buildNodes(ComplexListNode pNode, ComplexListNode pNext, ComplexListNode pSibling)
	{
		if(pNode != null)
		{
			pNode.m_pNext = pNext;
			pNode.m_pSibling = pSibling;
		}//if
	}
	
	public static void printList(ComplexListNode pHead)
	{
		ComplexListNode p = pHead;
		while(p != null)
		{
			if(p.m_pSibling != null)
			{
				System.out.println(p.m_nValue + ":" + p.m_pSibling.m_nValue);
			}//if
			else
			{
				System.out.println(p.m_nValue);
			}//else
			p = p.m_pNext;
		}//while
	}
}

拷贝实现类

/****************************************************************************************
 *题目:复杂链表的复制
 *		请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。在复杂链表中,
 *		每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者nullptr。
 *时间:2015年9月6日09:02:22
 *文件:CopyComplextList.java
 *作者:cutter_point
 ****************************************************************************************/
package bishi.Offer50.y2015.m09.d06;

public class CopyComplextList
{	
	/**
	 * 把我们的链表进行克隆,把长度扩为2倍
	 * @param pHead
	 */
	private void coneNodes(ComplexListNode pHead)
	{
		ComplexListNode pNode = pHead;
		while(pNode != null)
		{
			ComplexListNode temp = new ComplexListNode(pNode.m_nValue);
			temp.m_pNext = pNode.m_pNext;
			pNode.m_pNext = temp;
			pNode = temp.m_pNext;
		}//while
	}
	
	//给我们的复制节点的sibling初始化
	private void connectSiblingNodes(ComplexListNode pHead)
	{
		if(pHead == null)
			return;
		ComplexListNode pNode = pHead;
		while(pNode != null)
		{
			ComplexListNode pCpNode = pNode.m_pNext;
			if(pNode.m_pSibling != null)
			{
				pCpNode.m_pSibling = pNode.m_pSibling.m_pNext;
			}//if
			pNode = pCpNode.m_pNext;
		}//while
	}
	
	private ComplexListNode reconnectNodes(ComplexListNode pHead)
	{
		if(pHead == null)
			return null;
		ComplexListNode pNode = pHead;
		ComplexListNode pCHead = pNode.m_pNext;
		ComplexListNode pCpNode = pNode.m_pNext;
		while(pNode != null)
		{
			pNode.m_pNext = pCpNode.m_pNext;
			if(pNode.m_pNext != null)
				pCpNode.m_pNext = pNode.m_pNext.m_pNext;
			else
				pCpNode.m_pNext = null;
			pNode = pNode.m_pNext;
			pCpNode = pCpNode.m_pNext;
		}//while
		
		return pCHead;
	}
	
	public ComplexListNode copy(ComplexListNode pHead)
	{
		this.coneNodes(pHead);
		this.connectSiblingNodes(pHead);
		
		return this.reconnectNodes(pHead);
	}
	
	void Test(String testName, ComplexListNode pHead)
	{
	    if(testName != null)
	        System.out.print(testName + " begins:\n");

	    System.out.print("The original list is:\n");
	    ComplexListNode.printList(pHead);
	    CopyComplextList ccl = new CopyComplextList();
	    ComplexListNode pClonedHead = ccl.copy(pHead);

	    System.out.print("The cloned list is:\n");
	    ComplexListNode.printList(pClonedHead);
	}
	
	//-----------------
	//\|/              |
	//1-------2-------3-------4-------5
	//|       |      /|\             /|\
	//--------+--------               |
	//-------------------------
	@org.junit.Test
	public void test1()
	{
		ComplexListNode pNode1 = new ComplexListNode<Integer>(1);
		ComplexListNode pNode2 = new ComplexListNode<Integer>(2);
		ComplexListNode pNode3 = new ComplexListNode<Integer>(3);
		ComplexListNode pNode4 = new ComplexListNode<Integer>(4);
		ComplexListNode pNode5 = new ComplexListNode<Integer>(5);

		ComplexListNode.buildNodes(pNode1, pNode2, pNode3);
		ComplexListNode.buildNodes(pNode2, pNode3, pNode5);
		ComplexListNode.buildNodes(pNode3, pNode4, null);
		ComplexListNode.buildNodes(pNode4, pNode5, pNode2);

		Test("Test1", pNode1);
	}
	
	//m_pSibling指向结点自身
	//-----------------
	//\|/              |
	//1-------2-------3-------4-------5
	//|       | /|\           /|\
	//|       | --             |
	//|------------------------|
	@org.junit.Test
	public void test2()
	{
		ComplexListNode pNode1 = new ComplexListNode<Integer>(1);
		ComplexListNode pNode2 = new ComplexListNode<Integer>(2);
		ComplexListNode pNode3 = new ComplexListNode<Integer>(3);
		ComplexListNode pNode4 = new ComplexListNode<Integer>(4);
		ComplexListNode pNode5 = new ComplexListNode<Integer>(5);

		ComplexListNode.buildNodes(pNode1, pNode2, null);
		ComplexListNode.buildNodes(pNode2, pNode3, pNode5);
		ComplexListNode.buildNodes(pNode3, pNode4, pNode3);
		ComplexListNode.buildNodes(pNode4, pNode5, pNode2);

		Test("Test2", pNode1);
	}
	
	//m_pSibling形成环
	//-----------------
	//\|/              |
	//1-------2-------3-------4-------5
	//|              /|\
	//|               |
	//|---------------|
	@org.junit.Test
	public void Test3()
	{
		ComplexListNode pNode1 = new ComplexListNode<Integer>(1);
		ComplexListNode pNode2 = new ComplexListNode<Integer>(2);
		ComplexListNode pNode3 = new ComplexListNode<Integer>(3);
		ComplexListNode pNode4 = new ComplexListNode<Integer>(4);
		ComplexListNode pNode5 = new ComplexListNode<Integer>(5);
		
		ComplexListNode.buildNodes(pNode1, pNode2, null);
		ComplexListNode.buildNodes(pNode2, pNode3, pNode4);
		ComplexListNode.buildNodes(pNode3, pNode4, null);
		ComplexListNode.buildNodes(pNode4, pNode5, pNode2);

		Test("Test3", pNode1);
	}
	
	//只有一个结点
	@org.junit.Test
	public void Test4()
	{
		ComplexListNode pNode1 = new ComplexListNode<Integer>(1);
		ComplexListNode.buildNodes(pNode1, null, pNode1);

		Test("Test4", pNode1);
	}
	

	//鲁棒性测试
	@org.junit.Test
	public void Test5()
	{
		Test("Test5", null);
	}
	
	@org.junit.Test
	public void myMain()
	{
		test1();test2();Test3();Test4();Test5();
	}
	
	public static void main(String[] args)
	{
		
	}
}



最后输出:

Test1 begins:
The original list is:
1:3
2:5
3
4:2
5
The cloned list is:
1:3
2:5
3
4:2
5
Test2 begins:
The original list is:
1
2:5
3:3
4:2
5
The cloned list is:
1
2:5
3:3
4:2
5
Test3 begins:
The original list is:
1
2:4
3
4:2
5
The cloned list is:
1
2:4
3
4:2
5
Test4 begins:
The original list is:
1:1
The cloned list is:
1:1
Test5 begins:
The original list is:
The cloned list is:


我感觉这次做这个题的时候,开始确实很有思路,打草稿的时候,似乎也还可以实现,可是当我实际操作的时候,起始漏洞非常多,还有就是草稿打的很模糊,不清晰,最后只好放弃,因为太麻烦,最后参考了一下答案,还是做出来了,总之就是磕磕碰碰的完成了,这个题,恩掌握的不够清晰,过段时间,等我淡忘了,再回来看看这个题,是不是会有更好的解法呢?



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值