`

复制特殊链表

 
阅读更多

转自<http://blog.sina.com.cn/s/blog_69824c1f0100v4ob.html>

struct node
        {
             int data;
             struct node * next;
             struct node * random;
        };

        本题来源是ms的一道面试题,要求是将一条有特殊结构的链表进行复制,链表的结构如上,除了正常的2个域之外,多了一个random,它代表一个指向链表 上某一任意节点的指针,要求将该链表复制。如图,其中实线表示next域,虚线表示random域。

拷贝特殊链表,有随机指针 - 飞云 - 我是飞云


        难点分析:本题最难的部分就在于如何将random域完好无损的完全拷贝复制到新的链表之上,对于普通链表一个while循环拷贝就可以搞定,但是这里似乎不可行。

        突破点:如何保存或记录random域可以作为一个思考的参考点,下面提供2种解法:
        1. hash缓存: 我们可以定义一个hash表,key为被拷贝链表中Node的地址,value为新的拷贝链表中Node的值。下面将在伪代码中进一步说明

        伪代码如下:
        struct node * old_list;
        struct node * new_list;

        hash ht;
        while( old_list != NULL )
        {
            if( ht.get(old_list) == NULL )   
        // 当前节点没有被复制过,则拷贝节点,同时将原节点的地址作为key,插入hash表
            {
            new_node = copy(*old_list);
            ht.set(old_list, new_node);
        }
        else    // 已经存在则直接将该节点读出
        {
            new_node = ht.get(old_list);
        }
          // 并将新复制的节点插入链表
          insert(new_list, new_node);
   
          if( ht.get(old_list->random) == NULL )   
          // 如果ht的random不存在,那么产生一个random node,并放入hash表
          {
                random_node = copy(*(old_list->random));
                ht.set(old_list->ramdon,random_node);
        }
            else    //否则从hash表中读出random
          {
              random_node = ht.get(old_list->random);
            }
            // 将random域进行填充
            new_node->random = random_node;
        }

        这样可以看出,因为地址值是唯一存在的,所以Hash函数的设计可以保证每个节点的值都会被一一映射,并且由于每一个节点都只会被复制一次,并且在代码的遍历过程中就已经完全复制好,空间复杂度为O(n),时间复杂度为O(n)

        2. 用一个图的方法看的比较清楚,首先在遍历原来链表的过程中,插入新的节点,比如A_N是copy(A_O)的,同时将A_N->next = A_O->next; A_O->next = A_N;通过一个遍历,我们就可以将链表复制成图中的样子。在完成next域的链接后,需要开始做random域的复制。

拷贝特殊链表,有随机指针 - 飞云 - 我是飞云


        在实现了next的结构之后,我们需要开始对new_list的random域和next域进行赋值。
        那么有: A_N->random = A_O->random->next;
        入图所示:A_O->random为C_O,C_O的next为C_N,这样A_N->random = C_N;
        对于 A_N->next = A_N->next->next;即B_N;
        该算法复杂度为O(N),空间复杂度为O(1),除了新拷贝的空间之外没有额外地址;

分享到:
评论

相关推荐

    剑指offer~复杂链表的复制(Java)

    输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会...

    剑指Offer(Python多种思路实现):复杂链表的复制

    题:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序...

    算法:算法C语言实现 第1-4部分 基础知识、数据结构、排序及搜索

     4.7 复制和索引项  4.8 一级ADT  4.9 基于应用的ADT示例  4.10 展望  第5章 递归与树  5.1 递归算法  5.2 分治法  5.3 动态规划  5.4 树  5.5 树的数学性质  5.6 树的遍历  5.7 递归二叉树...

    西工大noj答案完整版.doc

    136.字符串复制 137.字符串加密编码 138.字符串逆序 139.字符串排序 140.字符串替换 141.字符串左中右 142.组合数 143.最次方数 144.最大乘积 145.最大整数 146.最小整数 147.最长回文子串 148.左上角 149.左下角

    零起点学通C++多媒体范例教学代码

    第17章 类的特殊成员 第2篇 高级篇 第19章 代码重用 第20篇 高级篇 第20章 友元类与嵌套类 第21章 流 第22章 命名空间 第23章 模板 第24章 异常和错误处理 第25章 补充知识 附录A ASCII码对照表 附录B C++的关键字 ...

    零起点学通C++学习_多媒体范例教学代码

    第17章 类的特殊成员 第2篇 高级篇 第19章 代码重用 第20篇 高级篇 第20章 友元类与嵌套类 第21章 流 第22章 命名空间 第23章 模板 第24章 异常和错误处理 第25章 补充知识 附录A ASCII码对照表 附录B ...

    C程序范例宝典(基础代码详解)

    实例021 特殊等式 26 实例022 求一个正整数的所有因子 27 实例023 一元钱兑换方案 28 实例024 对调数问题 29 实例025 数平方和运算的问题 30 1.5 数组 31 实例026 逆序存放数据 32 实例027 相邻元素...

    C语言通用范例开发金典.part2.rar

    1.4.2 获得二叉树的深度和根(链表结构) 144 范例1-56 获得二叉树的深度和根 144 ∷相关函数:BiTreeDepth函数 Root函数 1.4.3 树的插入(顺序结构) 147 范例1-57 树的插入 147 ∷相关函数:InsertChild函数 ...

    C语言通用范例开发金典.part1.rar

    1.4.2 获得二叉树的深度和根(链表结构) 144 范例1-56 获得二叉树的深度和根 144 ∷相关函数:BiTreeDepth函数 Root函数 1.4.3 树的插入(顺序结构) 147 范例1-57 树的插入 147 ∷相关函数:InsertChild函数 ...

    C 开发金典

    1.4.2 获得二叉树的深度和根(链表结构) 144 范例1-56 获得二叉树的深度和根 144 ∷相关函数:BiTreeDepth函数 Root函数 1.4.3 树的插入(顺序结构) 147 范例1-57 树的插入 147 ∷相关函数:InsertChild函数 ...

    c语言经典案例

    实例041 特殊的完全平方数 52 实例042 一数三平方 54 实例043 求等差数列 55 实例044 亲密数 56 实例045 自守数 57 第5章 运算符与表达式 60 实例046 求二元一次不定方程 61 实例047 可逆素数 63 实例048 判断闰年 ...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    11.9 链表的概念 182 11.10 枚举类型 184 11.10.1 枚举类型的定义和枚举变量的说明 184 11.10.2 枚举类型变量的赋值和使用 185 11.11 类型定义符typedef 12 位运算 12.1 位运算符C语言提供了六种位运算符: 189 ...

    严蔚敏:数据结构题集(C语言版)

    5.7.2 复制广义表 5.7.3 建立广义表的存储结构 第6章 树和二叉树 6.1 树的定义和基本术语 6.2 二叉树 6.2.1 二叉树的定义 6.2.2 二叉树的性质 6.2.3 二叉树的存储结构 6.3 遍历二叉树和线索二叉树 6.3.1 遍历...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    11.9 链表的概念 182 11.10 枚举类型 184 11.10.1 枚举类型的定义和枚举变量的说明 184 11.10.2 枚举类型变量的赋值和使用 185 11.11 类型定义符typedef 12 位运算 12.1 位运算符C语言提供了六种位运算符: 189 ...

    用c描述的数据结构演示软件

    一般情况下演示屏由图示、算法和变量三个窗口组成,特殊情况下将根据演示内容适当增加。一般情况下, 左侧图示窗口显示演示数据的逻辑结构或存储结构,右侧上方窗口显示算法文本,右侧下方窗口显示当前算法中各变量...

    数据结构演示软件

    一般情况下演示屏由图示、算法和变量三个窗口组成,特殊情况下将根据演示内容适当增加。一般情况下, 左侧图示窗口显示演示数据的逻辑结构或存储结构,右侧上方窗口显示算法文本,右侧下方窗口显示当前算法中各变量...

    数据结构的电子书(chm版)

    5、7、2 复制广义表 5、7、3 建立广义表的存储结构 单元测验 6、0、0 树和二叉树 6、1、0 树的定义和基本术语 6、2、0 二叉树 6、2、1 二叉树的定义 6、2、2 二叉树的性质 6、2、3 二叉树的存储结构 6、3、0 ...

    c语言数据结构

    5、7、2 复制广义表 5、7、3 建立广义表的存储结构 单元测验 6、0、0 树和二叉树 6、1、0 树的定义和基本术语 6、2、0 二叉树 6、2、1 二叉树的定义 6、2、2 二叉树的性质 6、2、3 二叉树的存储结构 6、3、0 ...

Global site tag (gtag.js) - Google Analytics