题目:请实现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. root-systerm-bin是什么program

    root-systerm-bin是什么program http://packages.ubuntu.com/lucid/root-system-bin

  2. C++对象的JSON序列化与反序列化探索完结-列表的序列化与反序列化

    在前两篇文章中,我们已经完成对普通对象以及复杂对象嵌套的序列化与反序列化,见如下地址: C++对象的JSON序列化与反序列化探索 C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化 ...

  3. Qt移植 Window --Linux

    1.把源代码复制到Linux目录,使用qmake命令,注意在shell中直接使用qmake命令注意设置PATH环境变量 2. 在目录中会生成Makeflie文件 3. make即可 /usr/bin/ ...

  4. [原创] linux课堂-学习笔记-目录及概况

    本学习笔记基于:网易云课堂-linux课堂 课时1Centos 6.4安装讲解46:14 课时2Centos 6.4桌面环境介绍与网络连接04:30 课时3 Linux目录结构介绍及内核与shell分 ...

  5. 如何建立一个“绑定友好的”usercontrol--wpf

    如何建立一个"绑定友好的"usercontrol--wpf 这几天在打算将以前用winform写的工具程序重构到wpf,顺便学习理解看过的wpf的知识. 因为程序设计到一个Exce ...

  6. Clone table header and set as the first element, and replace header's th with td

    Clone table header and replace header's th with td var tableHeaderRow = '#tableId tbody tr:nth-child ...

  7. JQuery的鼠标滚动事件

    jQuery(window).height()代表了当前可见区域的大小,而jQuery(document).height()则代表了整个文档的高度,可视具体情况使用. 注意当浏览器窗口大小改变时(如最 ...

  8. log4net 配置

    1.在项目中引入log4net.dll组件: 2.在App.congfig中做如下修改 在加入如下内容: 这个节点最好放在<configuration>下的第一个位置,不然在服务里会报错. ...

  9. PostgreSQL+PostGIS的使用 函数清单

    一. PostgreSQL与PostGIS的关系 PostgreSQL 是世界上技术最先进的开源数据库,其前身是1977年一个源于Berkeley名为Ingres的非关系型数据库,其项目领导人为Mic ...

  10. 10个优秀的Objective-C和iOS开发在线视频教程

    如果你自己开发iOS应用,你肯定会发现网上有很多资源.学习编程的一个最好的方法就是自己写代码,而开始写代码的最快的方式就是看其他人怎么写.我们从海量视频和学习网站中整理出了我 如果你自己开发iOS应用 ...