复杂链表的复制(带随机结点)

博客围绕含额外随机指针的链表深拷贝问题展开。先解释深拷贝概念,即源对象与拷贝对象相互独立。接着给出解题思路,分三步:复制老链表(不带随机结点)并插入老结点后、复制随机结点、拆分链表。还指出难点是随机结点复制,给出关键关系。最后表示将贴出详细代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
深拷贝:深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一 个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。(来自百度百科)
所以说,拷贝完不会对原链表产生任何影响。
那么???这道题的解题思路是什么呢?先看下图
在这里插入图片描述

方框代表老结点,菱形代表新结点,分3步:
1、复制老链表,此时复制的是不带随机结点random,并将新结点插入到老结点的 后边。
2、复制随机结点random
3、将链表拆分成老链表和新链表
进行完第2步,链表就如下图:
在这里插入图片描述
这道题的难点在于随机结点的复制,但是我们可以看到newNode->random就为oldNode->random->next
理解了这一点,这道题就容易啦,下面贴出详细代码:

 Node* copyRandomList(Node* head) {
        //分3步
        //1、将旧链表复制一份,不含随机指针的,将新结点插入到老结点的后面
        //2、根据老结点的random复制新结点的random
        //3、链表拆分
        if(head==NULL)
        {
            return NULL;
        }
      Node* oldNode=head;
        while(oldNode!=NULL)
        {
            Node* newNode=(Node*)malloc(sizeof(Node));
            newNode->val=oldNode->val;
            Node* oldNext=oldNode->next;
            newNode->next=oldNext;//
            oldNode->next=newNode;//
            oldNode=oldNext;
        }
        oldNode=head;//又让遍历的指针从头开始,只遍历老结点
        while(oldNode!=NULL)
        {
            Node* newNode=oldNode->next;
            if(oldNode->random==NULL)
            {
                newNode->random=NULL;
            }
            else
            {
                newNode->random=oldNode->random->next;
            }
            oldNode=newNode->next;
        }
        oldNode=head;
        Node* newHead=head->next;
        while(oldNode!=NULL)
        {
            Node* newNode=oldNode->next;
            oldNode->next=newNode->next;
            if(newNode->next!=NULL)
            {
                newNode->next=newNode->next->next;
            }
            oldNode=oldNode->next;
        }
        return newHead;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值