题目:请实现ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibing指向链表中的任意结点或者null。
struct ComplexListNode{
      int      m_nValue;
      ComplexListNode*     m_pNext;
      ComplexListNode*     m_pSibling;
}

分析思路:

第一步是根据原始链表的每个结点N创建对应的N',但是是把N'链接在N的后面。
第二步是设置复制出来的结点的m_pSibling。假设原始链表上的N的m_pSibling指向结点S,那么其对应复制出来的N'是N的m_pNext指向的结点,同样S'也是S的m_pNext指向的结点。
第三步是把这个长链表拆分成两个链表:把奇数位置的结点用m_pNext链接起来就是原始链表,把偶数位置的结点用m_pNext链接起来就是复制出来的链表。
 
测试用例:
1)功能测试(包括结点中的m_pSibling指向结点自身,两个结点的m_pSibling形成环状结构,链表中只有一个结点);
2)特殊输入测试(指向链表头结点的指针为null指针)。
 
代码实现:
package com.yyq;
/**
* Created by Administrator on 2015/9/20.
*/
public class CopyComplexList {
//第一步:复制每个结点
public static void cloneNodes(ComplexListNode pHead){
ComplexListNode pNode = pHead;
while(pNode != null){
ComplexListNode pCloned = new ComplexListNode();
pCloned.setM_nValue(pNode.getM_nValue());
pCloned.setM_pNext(pNode.getM_pNext());
pNode.setM_pNext(pCloned);
pNode = pCloned.getM_pNext();
}
}
//第二步:复制m_pSibling结点
public static void connectSiblingNodes(ComplexListNode pHead){
ComplexListNode pNode = pHead;
while (pNode != null){
ComplexListNode pCloned = pNode.getM_pNext();
if (pNode.getM_pSibling() != null){
pCloned.setM_pSibling(pNode.getM_pSibling().getM_pNext());
}
pNode = pCloned.getM_pNext();
}
}
//第三步:将这个长链表分成两个表
public static ComplexListNode reconnectNodes(ComplexListNode pHead){
ComplexListNode pNode = pHead;
ComplexListNode pClonedHead = null;
ComplexListNode pClonedNode = null;
if (pNode != null){
pClonedHead = pNode.getM_pNext();
pClonedNode = pNode.getM_pNext();
pNode.setM_pNext(pClonedNode.getM_pNext());
pNode = pNode.getM_pNext();
}
while(pNode != null){
pClonedNode.setM_pNext(pNode.getM_pNext());
pClonedNode = pClonedNode.getM_pNext();
pNode.setM_pNext(pClonedNode.getM_pNext());
pNode = pNode.getM_pNext();
}
return pClonedHead;
}
public static ComplexListNode clone(ComplexListNode pHead){
cloneNodes(pHead);
connectSiblingNodes(pHead);
return reconnectNodes(pHead);
}
// ====================测试代码====================
public static void Test(String testName, ComplexListNode pHead)
{
if(testName != null)
System.out.println(testName + " begins:");
System.out.println("The original list is:");
ComplexListNode pNode = new ComplexListNode();
pNode.printListNode(pHead);
ComplexListNode pClonedHead = clone(pHead);
System.out.println("The cloned list is:");
pNode.printListNode(pClonedHead);
}
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | | /|\ /|\
// --------+-------- |
// -------------------------
public static void Test1()
{
ComplexListNode pNode1 = new ComplexListNode(1);
ComplexListNode pNode2 = new ComplexListNode(2);
ComplexListNode pNode3 = new ComplexListNode(3);
ComplexListNode pNode4 = new ComplexListNode(4);
ComplexListNode pNode5 = new ComplexListNode(5);
pNode1.buildNodes(pNode2, pNode3);
pNode2.buildNodes(pNode3, pNode5);
pNode3.buildNodes(pNode4, null);
pNode4.buildNodes(pNode5, pNode2);
Test("Test1", pNode1);
}
// m_pSibling指向结点自身
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | | /|\ /|\
// | | -- |
// |------------------------|
public static void Test2()
{
ComplexListNode pNode1 = new ComplexListNode(1);
ComplexListNode pNode2 = new ComplexListNode(2);
ComplexListNode pNode3 = new ComplexListNode(3);
ComplexListNode pNode4 = new ComplexListNode(4);
ComplexListNode pNode5 = new ComplexListNode(5);
pNode1.buildNodes(pNode2, null);
pNode2.buildNodes(pNode3, pNode5);
pNode3.buildNodes(pNode4, pNode3);
pNode4.buildNodes(pNode5, pNode2);
Test("Test2", pNode1);
}
// m_pSibling形成环
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | /|\
// | |
// |---------------|
public static void Test3()
{
ComplexListNode pNode1 = new ComplexListNode(1);
ComplexListNode pNode2 = new ComplexListNode(2);
ComplexListNode pNode3 = new ComplexListNode(3);
ComplexListNode pNode4 = new ComplexListNode(4);
ComplexListNode pNode5 = new ComplexListNode(5);
pNode1.buildNodes(pNode2, null);
pNode2.buildNodes(pNode3, pNode4);
pNode3.buildNodes(pNode4, null);
pNode4.buildNodes(pNode5, pNode2);
Test("Test3", pNode1);
}
// 只有一个结点
public static void Test4()
{
ComplexListNode pNode1 = new ComplexListNode(1);
pNode1.buildNodes(null, pNode1);
Test("Test4", pNode1);
}
// 鲁棒性测试
public static void Test5()
{
Test("Test5", null);
}
public static void main(String[] args)
{
Test1();
Test2();
Test3();
Test4();
Test5();
}
}
 
结果输出:
Test1 begins:
The original list is:
The value of this node is: 1
The value of its sibling is: 3
 
The value of this node is: 2
The value of its sibling is: 5
 
The value of this node is: 3
This node does not have a sibling.
 
The value of this node is: 4
The value of its sibling is: 2
 
The value of this node is: 5
This node does not have a sibling.
 
The cloned list is:
The value of this node is: 1
The value of its sibling is: 3
 
The value of this node is: 2
The value of its sibling is: 5
 
The value of this node is: 3
This node does not have a sibling.
 
The value of this node is: 4
The value of its sibling is: 2
 
The value of this node is: 5
This node does not have a sibling.
 
Test2 begins:
The original list is:
The value of this node is: 1
This node does not have a sibling.
 
The value of this node is: 2
The value of its sibling is: 5
 
The value of this node is: 3
The value of its sibling is: 3
 
The value of this node is: 4
The value of its sibling is: 2
 
The value of this node is: 5
This node does not have a sibling.
 
The cloned list is:
The value of this node is: 1
This node does not have a sibling.
 
The value of this node is: 2
The value of its sibling is: 5
 
The value of this node is: 3
The value of its sibling is: 3
 
The value of this node is: 4
The value of its sibling is: 2
 
The value of this node is: 5
This node does not have a sibling.
 
Test3 begins:
The original list is:
The value of this node is: 1
This node does not have a sibling.
 
The value of this node is: 2
The value of its sibling is: 4
 
The value of this node is: 3
This node does not have a sibling.
 
The value of this node is: 4
The value of its sibling is: 2
 
The value of this node is: 5
This node does not have a sibling.
 
The cloned list is:
The value of this node is: 1
This node does not have a sibling.
 
The value of this node is: 2
The value of its sibling is: 4
 
The value of this node is: 3
This node does not have a sibling.
 
The value of this node is: 4
The value of its sibling is: 2
 
The value of this node is: 5
This node does not have a sibling.
 
Test4 begins:
The original list is:
The value of this node is: 1
The value of its sibling is: 1
 
The cloned list is:
The value of this node is: 1
The value of its sibling is: 1
 
Test5 begins:
The original list is:
The cloned list is:

P147、面试题26:复杂链表的复制的更多相关文章

  1. 《剑指offer》面试题26 复杂链表的复制 Java版

    (定义一个新的数据结构,每个节点除了具有普通链表的next域外,还有一个额外的引用指向任意节点.我们要对由该特殊数据结构形成的链表进行复制.) 我的方法:也就是克隆一个这种特殊链表,很快想到先不考虑原 ...

  2. 剑指offer-面试题35-复杂链表的复制-链表

    /* 题目: 实现一个函数,复制复杂链表,返回复制链表的头节点. */ /* 思路: 第一步,复制一个链表S‘,插在原链表S中. 第二步,链表S’复制链表S的random指针. 第三步:拆分链表S和S ...

  3. 剑指offer面试题26-复杂链表的复制

    题目: 请实现函数ComplexListNode* Clone(ComplexListNode* pHead).复制一个复杂链表. 在复杂链表中.每个节点除了一个m_pNext指针指向下一个节点外,另 ...

  4. 《剑指offer》面试题35. 复杂链表的复制

    问题描述 请实现 copyRandomList 函数,复制一个复杂链表.在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null. ...

  5. 剑指offer 面试题35.复杂链表的复制

    时间O(N),空间O(N) /* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomList ...

  6. (剑指Offer)面试题26:复杂链表的复制

    题目: 请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表. 在复杂链表中,每个结点除了有一个pNext指针指向下一个结点之外,还 ...

  7. 剑指offer面试题26:复杂链表的复制

    题目:请实现一个函数,复制一个复杂链表. 在复杂链表中,每个结点除了有一个next指针指向下一个结点外,还有一个sibling指针指向链表中的任意结点或者nulL 直观解法: 1.遍历链表,复制链表节 ...

  8. 【剑指Offer学习】【面试题26:复杂链表的复制】

    题目:请实现函数ComplexListNode clone(ComplexListNode head),复制一个复杂链表. 在复杂链表中,每一个结点除了有一个next 域指向下一个结点外,另一个sib ...

  9. 剑指Offer面试题:24.复杂链表的复制

    一.题目:复杂链表的复制 题目:请实现函数ComplexListNode Clone(ComplexListNode head),复制一个复杂链表.在复杂链表中,每个结点除了有一个Next指针指向下一 ...

  10. 剑指offer-第四章解决面试题思路(复杂链表的复制)

    题目:请写一个函数clone(ComplexListNode pHead),实现复杂链表的复制. 复杂链表的数据结构如下:public class ComplexListNode{int m_nVal ...

随机推荐

  1. [Guava学习笔记]Collections: 不可变集合, 新集合类型

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3843386.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  2. Shell 循环读取文件

    使用Shell将Windows环境下的文件拷贝到Linux下面的用法. 在linux下,将dos文件格式转换成linux文件格式的用法,vi打开,然后转到命令格式,执行,然后保存,就可以转换成linu ...

  3. ecshop中无限处理分类

    数据库表记录结构 <?php $sql = "SELECT c.cat_id, c.cat_name, c.measure_unit, c.parent_id, c.is_show, ...

  4. [原创] linux课堂-学习笔记-课程3.Linux目录结构介绍及内核与shell分析

    一.目录说明 1.1 bin 一般用户,可执行的系统内置命令 1.2 sbin 系统管理员,可执行的系统内置命令 1.3 boot 启动文件目录,启动有关的文件都保存在此 1.4 dev 设备管理文件 ...

  5. Xubuntu下Mentohust认证(校园网用户)

    对于路由器上网到用户来说,自动分配IP上网。 对于校园网用户,首先下载mentohust_0.3.4-1_i386.deb,双击安装程序 然后在命令窗口中输入sudo -s 密码:user来获得roo ...

  6. 【 socke】C# socket端口复用-多主机头绑定

    什么是端口复用: 因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分.这种多重绑定便称之为端口复用 ...

  7. HTML 菜单 a 标签跳转本页面并追加参数

    代码如下: <!-- BEGIN 追加URL的参数 --> <script type="text/javascript"> function setUrl( ...

  8. python学习笔记29(python中堆的使用)

    堆(heap):优先队列的一种,使用优先队列能够以任意顺序增加对象,并且能在任意时间(可能在增加对象的同时)找到(也可能是移除)最小元素,比用于列表中min的方法要高效. Python中并没有独立的堆 ...

  9. vc编程时说“Cannot open include file: 'unistd.h': No such file or directory”

    本文专自http://blog.csdn.net/mangobar/article/details/6314700 unistd.h是unix standard header之意,因此,Linux下开 ...

  10. [转]BluetoothDevice.getType()-一个常常被忽略了的函数。好用的不要不要的

    自动安卓发布了4.0版本的蓝牙协议之后,越来越多的开发者收到了各种针对于BLE蓝牙的开发需求. 而且有很多时候还需要兼容以前的3.0版本,给大家的开发带来了困扰,笔者也遇到了这样的问题,偶然间发现了g ...