随机链表的复制

后插节点解答

        实现目标,要将复杂问题拆解为较为解决的较小问题进行逐步解决。可以将要复制的链表分为节点插入到每个原链表的节点后面,如图所示:

1.插入复制节点       

        想要实现如图所示效果,首先用malloc创建节点,然后后插入每个原节点的后面,这里要注意的是,应该先改变插入节点的next指针,防止因为覆盖导致原指针的next指针无法被找到。代码如下:

struct Node* cur = head;
    while(cur)
    {
        //创建节点
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;

        copy->next = cur->next;
        cur->next = copy;

        cur = copy->next;//通过赋值让cur继续往后走
    }

结束条件以cur为主体确定:cur走到空停止。

2.控制random

        通过后插节点解答的优越性就体现出来了,将难以寻找的random节点通过后插copy节点实现新的copy节点的random指针在原节点的random指针的下一个位置。代码实现如下:

cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;;
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;//此解法的优势所在
        }
        cur = copy->next;//cur往后走   
    }

3.将效果实现好的copy从原链表中拆解为独立的新链表(恢复原链表)

        在这里我们为了防止覆盖要多创建一个next指针存放节点位置,并定义头节点与尾指针来进行尾插的实现。循环的主体仍是cur。代码实现如下:

cur = head;
    struct Node* copytail = NULL, *copyhead = NULL;
    while(cur)
    {
        struct Node* copy = cur->next;
        struct Node* next = copy->next;  

        if(copytail == NULL)
        {
            copyhead = copytail = copy;
        }
        else
        {
            copytail->next = copy;
            copytail = copytail->next;
        }
        cur->next = next;//恢复原链表
        cur = next;
    }
    return copyhead;

        像这样,通过化繁为简的方法将复杂的问题分为三块较为简单的函数,就可以解决问题了。

最后,我们将代码整合起来,即为:

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */

struct Node* copyRandomList(struct Node* head) 
{
	struct Node* cur = head;
    while(cur)
    {
        //创建节点
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;

        copy->next = cur->next;
        cur->next = copy;

        cur = copy->next;//copy往后走
    }
    //控制random
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;;
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;//此解法的优势所在
        }
        cur = copy->next;//cur往后走   
    }
    //将copy节点尾插到新链表中
    cur = head;
    struct Node* copytail = NULL, *copyhead = NULL;
    while(cur)
    {
        struct Node* copy = cur->next;
        struct Node* next = copy->next;  

        if(copytail == NULL)
        {
            copyhead = copytail = copy;
        }
        else
        {
            copytail->next = copy;
            copytail = copytail->next;
        }
        cur->next = next;//恢复原链表
        cur = next;
    }
    return copyhead;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值