剑指 Offer 35. 复杂链表的复制 C详解

本文详细介绍了如何复制带有额外random指针的复杂链表。通过在原链表中每个节点后插入副本节点的方式,解决了random指针的复制难题,并提供了完整的代码实现。

剑指 Offer 35. 复杂链表的复制



请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

示例 1:
在这里插入图片描述

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:
在这里插入图片描述

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]



思路:

假定以下链表。randon指向给出全部情况。指向别人,指向自己,指向NULL。
在这里插入图片描述

在每个节点后插入一个copy节点。

在这里插入图片描述

代码示例:

  			Node* cur =head;

            while(cur)
            {
                Node* newNode = (Node*)malloc(sizeof(Node));
                newNode->val = cur->val;
                newNode->next = cur->next;
                cur->next = newNode;

                cur = newNode->next;
            }


通过观察发现,每一个copy节点的random都是它上一个节点的random指向的下一个节点。
在这里插入图片描述


代码示例:

			cur = head;
	        while(cur)
            {
                Node* newNode = cur->next;
                
                if(cur->random)//注意random指向NULL,
                    newNode->random = cur->random->next;    
                else
                newNode->random = NULL;

                cur = newNode->next;
            }



最后,分割两个链表。

//分割链表。  
			//保留copy链表的头
            Node* copyhead = head->next;
            cur = head;

            while(cur)
            {
                Node* newNode = cur->next;
                Node* next = newNode->next;

                if(next)//注意空指针访问
                    newNode->next = next->next;
                else
                    newNode->next =NULL;

                cur->next = next;

                cur =next;
            }


总体代码示例:

Node* copyRandomList(Node* head) {

        if(head == NULL)
            return head;

            Node* cur =head;
			//1,添加copy节点
            while(cur)
            {
                Node* newNode = (Node*)malloc(sizeof(Node));
                newNode->val = cur->val;
                newNode->next = cur->next;
                cur->next = newNode;

                cur = newNode->next;
            }

			//2.复制random
            cur = head;
            while(cur)
            {
                Node* newNode = cur->next;
                if(cur->random)
                    newNode->random = cur->random->next;    
                else
                newNode->random = NULL;

                cur = newNode->next;
            }

             
            //3.分割链表。  
            Node* copyhead = head->next;
            cur = head;

            while(cur)
            {
                Node* newNode = cur->next;
                Node* next = newNode->next;

                if(next)
                    newNode->next = next->next;
                else
                    newNode->next =NULL;

                cur->next = next;

                cur =next;
            }

        return copyhead;   
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

necesse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值