【数据结构---15】复杂链表的深度复制

题目描述:

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点

要求返回这个链表的深拷贝

示例:

在这里插入图片描述

输入:

{"$id":"1","next":
{"$id":"2","next":null,"random":
{"$ref":"2"},"val":2},"random":
{"$ref":"2"},"val":1}

解释
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    Node() {}
    Node(int _val, Node* _next, Node* _random) {
        val = _val;
        next = _next;
        random = _random;
 }    
};
*/

思路分析:

<1>在原有链表每个节点后面插入一个值相同的新节点
<2>对插入的新节点的随机指针域赋值
<3>将插入的新节点从原链表中拆出来
注意:
1.循环中语句的顺序
2.插入新节点的循环跳出条件是p1->next!=NULL,需要出循环之后单独处理
3.跳出条件如果为p1!=NULL,会发生段错误
4.给随机指针域赋值时,p1->random可能为空,需要分情况处理

代码实现:

    class Solution {
public:
    Node* BuyNode(int val)
    {
            Node* newnode=(Node*)malloc(sizeof(Node));
            if(newnode==NULL)
            {
                assert(0);
            }
            newnode->val=val;
            newnode->next=NULL;
            newnode->random=NULL;
            return newnode;
    }
        
    Node* copyRandomList(Node* head) 
    {   
        if(head==NULL)
        {
            return NULL;
        }        
        
        //原链表中每个节点后都插入一个值相同的节点
        Node* p1=head;
        while(p1->next!=NULL)
        {
            Node* node=BuyNode(p1->val);
            node->next=p1->next;
            p1->next=node;
            p1=node->next;
            node=p1->next;
        }
        Node* node=BuyNode(p1->val);
        p1->next=node;
        node->next=NULL;  
              
        //给新插入的节点的随机指针域赋值
        p1=head;
        Node* p2=head->next;      
        Node* phead=p2;      
        while(p1!=NULL)
        {
            if(p1->random!=NULL )
            {
                p2=p1->next;
                p2->random=p1->random->next;
                p1=p2->next;               
            }
            else
            {
                p2=p1->next;
                p2->random=NULL;
                p1=p2->next;
            }
        }
        
        //将新插入的节点从原链表中拆出来
        p1=head;
        p2=head->next;
        while(p1->next!=NULL)
        {
            p1->next=p2->next;
            p1=p2;
            p2=p1->next;
        }     
        return phead;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值