【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾

这篇具有很好参考价值的文章主要介绍了【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode

目录

 1.随机链表的复制

1.2题目描述 

1.3题目分析

1.4解题:

2.顺序表和链表对比

2.1cpu高速缓存利用率

3.结语


 1.随机链表的复制

一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random 

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode

该指针可以指向链表中的任何节点或空节点。 

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode 

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode 

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode 

1.2题目描述 

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

1.3题目分析

首先,链表的拷贝如果是普通链表的话,使用遍历+尾插即可。

深度拷贝就是要链表结构也一样

但是由于随机指针的存在。我们没办法知道或者就是说我们拷贝的节点的随机指针该指向那个位置。那么就有一种简单粗暴的方法:

遍历链表然后匹配随机指针。

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode

那么巧妙的一种办法,就是将复制的节点插到被复制节点的后面,这种方法巧妙。时间复杂度为O(N).空间复杂度也为O(1).

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode

while(cur)//循环申请插入
    {
        //每次都申请节点
         struct Node* copy = ( struct Node*)malloc(sizeof( struct Node));
         //尾插
         cur->val = copy->val;
         cur ->next = copy;
         copy->next = next;
         cur = next;
         //往后走一步
         next = cur->next;

    
    }

 那么对于随机指针的连接:
【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode

我们发现,我们原链表的节点的随机指针指向的节点的next刚好就是我们复制链表节点的随机指针要指向的节点,所以:

 //还要使用cur遍历
    cur = head;
    struct Node* copy = cue->next;
    while(cur)
    {
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;
        }
        cur = copy->next;
        copy = cur->next;
    }

然后我们将复制的节点从原链表取下来尾插成新的链表,复原原链表就OK了:

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode

1.4解题:

 

struct Node* copyRandomList(struct Node* head) {
	
    //1.首先先将复制的节点尾插到各个节点的后面
    assert(head);//断言,不能传入一个空链表
    struct Node* cur = head;
     struct Node* next = cur->next;

    while(cur)//循环申请插入
    {
        //每次都申请节点
         struct Node* copy = ( struct Node*)malloc(sizeof( struct Node));
         //尾插
         cur->val = copy->val;
         cur ->next = copy;
         copy->next = next;
         cur = next;
         //往后走一步
         next = cur->next;

    
    }

    //还要使用cur遍历
    cur = head;
    struct Node* copy = cur->next;
    while(cur)
    {
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;
        }
        cur = copy->next;
        copy = cur->next;
    }
     cur = head;
      struct Node* copyhead = NULL;//新链表的头结点
       struct Node* copytail = NULL;//定义一个尾结点方便尾插
       //还是遍历解除复原
       while(cur)
       {
           copy = cur->next;
           next = copy->next;
           //将cope结点开始尾插
           if(copytail == NULL)//此时新链表一个元素都没有
           {
               copyhead = copytail = copy;
           }
           else
           {
               copytail->next = copy;
               copytail = copytail->next;
           }
           cur ->next = next;
           cur =next;


       }
       return copyhead;

}

2.顺序表和链表对比

    不同点                 顺序表                                                                   链表

存储空间上    物理上一定连续                                           逻辑上连续,但物理上不一定 连续

随机访问         支持O(1)                                                            不支持:O(N)

 任意位置插入或者删除元素可能需要搬移元素,效率低 O(N)     只需修改指针指向 

插入          动态顺序表,空间不够时需要 扩容                                没有容量的概念

应用场景       元素高效存储+频繁访问                                    任意位置插入和删除频繁 

缓存利用率                    高                                                                  低

2.1cpu高速缓存利用率

硬件上的存储分层如下图:

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾,数据结构与算法初阶(C语言),数据结构,c语言,链表,算法,开发语言,leetcode 

3.结语

 链表和顺序表的知识到这里基本就告一段落,那么大家可以从知识到解题详细回顾一下。

可以结合图解多看一下代码,结合理解。以上就是本期的所有内容,知识含量蛮多,大家可以配合解释和原码运行理解。创作不易,大家如果觉得还可以的话,欢迎大家三连,有问题的地方欢迎大家指正,一起交流学习,一起成长,我是Nicn,正在c++方向前行的奋斗者,数据结构内容持续更新中,感谢大家的关注与喜欢。文章来源地址https://www.toymoban.com/news/detail-838008.html

到了这里,关于【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构初阶】四、线性表里的链表(带头+双向+循环 链表 -- C语言实现)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】三、 线性表里的链表(无头+单向+非循环链表 -- C语言实现)-CSDN博客  ====

    2024年02月08日
    浏览(44)
  • 『初阶数据结构 • C语言』⑨ - 基于结点的数据结构——链表(单链表&&双向循环链表)附完整源码

      本章内容 1.什么是链表 2.链表常见几种形式 3.无头单向非循环链表的实现 3.1结点结构的定义 3.2函数接口的实现 3.2.1尾插 3.2.2尾删 4. 带头双向循环链表的实现 4.1结点结构的定义 4.2函数接口的实现 5.两种链表的差异 ①尾插与尾删的时间复杂度 ②头插与头删的时间复杂度 ③

    2024年02月16日
    浏览(81)
  • 【数据结构和算法】实现带头双向循环链表(最复杂的链表)

    前文,我们实现了认识了链表这一结构,并实现了无头单向非循环链表,接下来我们实现另一种常用的链表结构,带头双向循环链表。如有仍不了解单向链表的,请看这一篇文章(7条消息) 【数据结构和算法】认识线性表中的链表,并实现单向链表_小王学代码的博客-CSDN博客

    2024年01月17日
    浏览(78)
  • 【数据结构与算法——TypeScript】算法的复杂度分析、 数组和链表的对比

    什么是算法复杂度(现实案例)? ❤️‍🔥 前面已经解释了什么是算法? 其实就是解决问题的一系列步骤操作、逻辑。 ✅ 对于同一个问题,我们往往有很多种解决思路和方法,也就是可以采用不同的算法。 举个例子(现实例子):在一个庞大的图书馆中,我们需要找一本书

    2024年02月14日
    浏览(52)
  • 【数据结构初阶】三、 线性表里的链表(无头+单向+非循环链表 -- C语言实现)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表)-CSDN博客  =========================

    2024年02月08日
    浏览(56)
  • 『初阶数据结构 • C语言』② - 算法为何重要

    本文内容借鉴一本我非常喜欢的书——《数据结构与算法图解》。学习之余,我决定把这本书精彩的部分摘录出来与大家分享。   算法这个词听起来很深奥,其实不然。它只是解决某个问题的一套流程。  准备一碗麦片的流程也可以说是一种算法,它包含以下 4步(对我来说

    2024年02月14日
    浏览(38)
  • [数据结构-C语言] 算法的时间复杂度

    目录 1.算法的复杂度 2.时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 3、常见时间复杂度计算举例 3.1 冒泡排序 3.2 二分查找 3.3 阶乘递归 3.4 斐波那契数列 1.算法的复杂度 算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源 。因此 衡量一个算法的

    2024年02月02日
    浏览(47)
  • 第11章:C语言数据结构与算法初阶之排序

    排序是一种非常重要的算法。 排序 :所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性 :假定在待排序的记录序列中,存在多个具有相同的的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,

    2024年02月12日
    浏览(46)
  • 『初阶数据结构 • C语言』③ - 算法分析专业工具——大O记法

    本文内容借鉴一本我非常喜欢的书——《数据结构与算法图解》。学习之余,我决定把这本书精彩的部分摘录出来与大家分享。        从之前的章节中我们了解到,影响算法性能的主要因素是其所需的步数。 然而,我们不能简单地把一个算法记为“22步算法”,把另一个算

    2024年02月16日
    浏览(47)
  • 【数据结构初阶】一. 复杂度讲解

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 学C的第三十四天【程序环境和预处理】_高高的胖子的博客-CSDN博客  ===============================

    2024年02月10日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包