C语言编程实战:每日一题:随机链表的复制

编程达人挑战赛·第5期 10w+人浏览 171人参与

欢迎来到 s a y − f a l l 的文章 欢迎来到say-fall的文章 欢迎来到sayfall的文章

在这里插入图片描述


🌈这里是say-fall分享,感兴趣欢迎三连与评论区留言
🔥专栏: 《C语言从零开始到精通》 《C语言编程实战》 《数据结构与算法》 《小游戏与项目》
💪格言:做好你自己,你才能吸引更多人,并与他们共赢,这才是你最好的成长方式。



题目:随机链表的复制

一、思路解析

该代码采用 “原地复制+拆分” 策略,高效实现复杂链表(每个节点含valnext指针、random指针)的深拷贝,核心优势是 时间复杂度O(n)、空间复杂度O(1)(不考虑目标链表存储空间),具体分3步:

1. 第一步:原地插入拷贝节点(构建“原节点-拷贝节点”成对结构)

  • 遍历原链表的每个节点pcur,为其创建一个拷贝节点NewNode(值与原节点相同,random初始为NULL)。
  • 将拷贝节点插入到原节点的后面(即NewNode->next = pcur->next,再pcur->next = NewNode)。
  • 最终原链表结构变为:原节点1 -> 拷贝节点1 -> 原节点2 -> 拷贝节点2 -> ... -> 原节点n -> 拷贝节点n -> NULL

2. 第二步:设置拷贝节点的random指针

  • 再次遍历原链表(仅遍历原节点,步长为2:pcur = pcur->next->next)。
  • 对于每个原节点pcur,其拷贝节点是pcur->next
    • 若原节点pcurrandomNULL,则拷贝节点的random也为NULL
    • 若原节点pcurrandom指向原链表中的某节点A,则拷贝节点的random应指向A的拷贝节点(即A->next),这是该方法的核心巧思(利用第一步构建的成对结构,直接通过原节点的random找到拷贝节点)。

3. 第三步:拆分原链表与拷贝链表

  • 原链表的第一个拷贝节点(head->next)即为新链表的头节点Newhead
  • 遍历拷贝链表(步长为2:pcur = pcur->next->next),将拷贝节点的next指针指向下一个拷贝节点(跳过原节点),最终拆分出独立的拷贝链表。
  • 原链表结构在拆分后会恢复(可选,该代码未显式恢复,但不影响拷贝结果)。

二、流程图

开始
原链表head是否为NULL?
返回NULL
结束
初始化pcur = head
pcur ≠ NULL?
调用BuyNode创建拷贝节点
(val=pcur->val,next=pcur->next)
prev = pcur,pcur = pcur->next
prev->next = 拷贝节点
(插入原节点后)
重置pcur = head
【步骤1完成:原-拷成对结构】
pcur ≠ NULL 且 pcur->next ≠ NULL?
pcopy = pcur->next(获取拷贝节点)
pcur->random 是否为NULL?
pcopy->random = NULL
pcopy->random = pcur->random->next
(指向原random的拷贝节点)
pcur = pcur->next->next(跳过拷贝节点)
【步骤2完成:random指针设置完毕】
Newhead = head->next(拷贝链表头)
pcur = Newhead
pcur ≠ NULL 且 pcur->next ≠ NULL?
pcur->next = pcur->next->next
(跳过原节点,连接下一个拷贝节点)
pcur = pcur->next(移动到下一个拷贝节点)
【步骤3完成:链表拆分完毕】
返回Newhead

三、关键

  1. BuyNode函数作用:封装拷贝节点的创建逻辑,确保拷贝节点的next初始指向原节点的下一个节点,random初始为NULL
  2. random指针设置的核心:利用“原节点后紧跟拷贝节点”的结构,原节点Arandom指向B,则拷贝节点A'random必然指向B'B->next)。
  3. 拆分逻辑:拷贝链表的节点在原链表中是“隔一个”存在的,因此只需将每个拷贝节点的next指向其下一个拷贝节点(pcur->next->next)即可拆分出独立的拷贝链表。

四、代码

typedef struct Node Node;
Node* BuyNode(int x,Node* pcur)
{
    Node* NewNode = (Node*)malloc(sizeof(Node));
    NewNode->val = x;
    NewNode->next = pcur->next;
    NewNode->random = NULL;
    return NewNode;
}
struct Node* copyRandomList(struct Node* head) 
{
    if(head == NULL)
    {
        return NULL;
    }
    Node* pcur = head;
	while(pcur)
    {
        Node* NewNode = BuyNode(pcur->val,pcur);
        Node* prev = pcur;
        pcur = pcur->next;
        prev->next = NewNode;
    }
    pcur = head;
    while(pcur != NULL && pcur->next != NULL)
    {
        Node* pcopy = pcur->next; 
        if(pcur->random == NULL)
        {
            pcopy->random = NULL;
        }
        else
        {
            pcopy->random = pcur->random->next;
        }
        pcur = pcur->next->next;
    }
    Node* Newhead = head->next;
    pcur = Newhead;
    while(pcur!= NULL && pcur->next != NULL)
    {
        pcur->next = pcur->next->next;
        pcur = pcur->next;
    }
    return Newhead;
}

  • 本节完…
内容概要:本文档围绕六自由度机械臂的ANN人工神经网络设计展开,涵盖正向与逆向运动学求解、正向动力学控制,并采用拉格朗日-欧拉法推导逆向动力学方程,所有内容均通过Matlab代码实现。同时结合RRT路径规划与B样条优化技术,提升机械臂运动轨迹的合理性与平滑性。文中还涉及多种先进算法与仿真技术的应用,如状态估计中的UKF、AUKF、EKF等滤波方法,以及PINN、INN、CNN-LSTM等神经网络模型在工程问题中的建模与求解,展示了Matlab在机器人控制、智能算法与系统仿真中的强大能力。; 适合人群:具备一定Ma六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)tlab编程基础,从事机器人控制、自动化、智能制造、人工智能等相关领域的科研人员及研究生;熟悉运动学、动力学建模或对神经网络在控制系统中应用感兴趣的工程技术人员。; 使用场景及目标:①实现六自由度机械臂的精确运动学与动力学建模;②利用人工神经网络解决传统解析方法难以处理的非线性控制问题;③结合路径规划与轨迹优化提升机械臂作业效率;④掌握基于Matlab的状态估计、数据融合与智能算法仿真方法; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点理解运动学建模与神经网络控制的设计流程,关注算法实现细节与仿真结果分析,同时参考文中提及的多种优化与估计方法拓展研究思路。
内容概要:本文围绕电力系统状态估计中的异常检测与分类展开,重点介绍基于Matlab代码实现的相关算法与仿真方法。文章详细阐述了在状态估计过程中如何识别和分类量测数据中的异常值,如坏数据、拓扑错误和参数误差等,采用包括残差分析、加权最小二乘法(WLS)、标准化残差检测等多种经典与现代检测手段,并结合实际算例验证方法的有效性。同时,文档提及多种状态估计算法如UKF、AUKF、EUKF等在负荷突变等动态场景下的应用,强调异常处理对提升电力系统运行可靠性与安全性的重要意义。; 适合人群:具备电力系统基础知识和一定Matlab编程能力的高校研究生、科研人员及从事电力系【状态估计】电力系统状态估计中的异常检测与分类(Matlab代码实现)统自动化相关工作的工程技术人员。; 使用场景及目标:①掌握电力系统状态估计中异常数据的产生机制与分类方法;②学习并实现主流异常检测算法,提升对状态估计鲁棒性的理解与仿真能力;③服务于科研项目、课程设计或实际工程中的数据质量分析环节; 阅读建议:建议结合文中提供的Matlab代码进行实践操作,配合电力系统状态估计的基本理论进行深入理解,重点关注异常检测流程的设计逻辑与不同算法的性能对比,宜从简单案例入手逐步过渡到复杂系统仿真。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值