题目:请实现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. lex&yacc2

    YACC: 每个归约后yacc 都执行默认动作,在运行任何明确的动作代码之前,将值$1 赋介$$. 下面是从这个语法中生成的 y.tab.h:#define NAME 257#define NUMBE ...

  2. xposed系列教程

    转载说明 本篇文章可能已经更新,最新文章请转:http://www.sollyu.com/xposed-series/ 说明 这是一篇XPOSED开发系列教程, 个人开发者,开发不容易.QQ群: 73 ...

  3. Linux 文件系统 相关

    鸟个讲得很详细啦:http://vbird.dic.ksu.edu.tw/linux_basic/0230filesystem_1.php 重要知识点:磁盘,文件系统,超级区块 (superblock ...

  4. 如何在Android SDK 下查看应用程序输出日志的方法

          该文章源于安卓教程网(http://android.662p.com),转载时要注明文章的来自和地址,感谢你的支持. 在Android程序中可以使用 android.util.Log 类来 ...

  5. CMakeLists实战解读--YouCompleteMe

    原文转载自:Ricky.K http://www.cnblogs.com/rickyk/p/3877238.html 个人一直有一个想法,就是想出一系列关于CMakeLists.txt国外经典例子的实 ...

  6. PyQt 5.2 发布,此版本完全支持Qtv5.2.0

    PyQt 5.2 发布,此版本完全支持Qtv5.2.0 :包括了新的 QtBluetooth,QtPositioning,QtMacExtras,QtWinExtras 和 Qt11Extras 模板 ...

  7. mySQL时间

    " and day='".date('Y-m-d',strtotime($day_g)). "'";  时间如: 2014-09-09 and day>= ...

  8. PHP微信开发代码

    1,SAE上申请服务器 2,绑定测试账号 3,Token验证 <?php /* http://www.cnblogs.com/xrhou12326/ CopyRight 2014 All Rig ...

  9. frame 之间访问

    index.asp代码 <frameset rows="50,*,20" cols="*" frameborder="no" bord ...

  10. java指令集

    0x00 nop      什么都不做 0x01 aconst_null 将null推送至栈顶 0x02 iconst_m1   将int型-1推送至栈顶 0x03 iconst_0   将int型0 ...