复杂链表的复制

题目

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

思路

复制一个新链表,但每复制一个结点都和原结点map建立一个对应关系。point->next在复制新链表的时候自然已有,然后轮询原链表,利用map对应关系,将新链表中的random进行赋值;

示例

-------------------------------------------------
输入的链表:
0 的下一个结点是: 1 随机结点是: 3
1 的下一个结点是: 2 随机结点是: 3
2 的下一个结点是: 3 随机结点是: 1
3 的下一个结点是: 4 随机结点是: 2
4 的下一个结点是:NULL 随机结点是: 1
---------------------------------------------------
输出的链表:
0 的下一个结点是: 1 随机结点是: 3
1 的下一个结点是: 2 随机结点是: 3
2 的下一个结点是: 3 随机结点是: 1
3 的下一个结点是: 4 随机结点是: 2
4 的下一个结点是:NULL 随机结点是: 1

代码

#include <iostream>
#include <vector>
#include <map>
using namespace std;

struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x),next(nullptr),random(nullptr){
    }
};

class Solution {
public:
    RandomListNode* Clone(RandomListNode *pHead)
    {
        if (pHead == NULL)
            return NULL;
        map<RandomListNode*, RandomListNode*> map_node;
        //用来遍历的指针pTail,换为currentPoint更好,但是不想动了,csdn不支持vim模式编译,替换很麻烦
        
        RandomListNode* pTail = pHead; 
        RandomListNode* cyHead = new RandomListNode(pHead->label);
        pTail = pTail->next;
        map_node[pHead] = cyHead;
        RandomListNode* cyHeadTail(cyHead);
        while(pTail) {
           RandomListNode* temp = new RandomListNode(pTail->label);
           
           // 每复制的结点都和相应结点用map建立对应关系,用来之后random的赋值
           map_node[pTail] = temp;
           
           // 复制没有random的链表
           cyHeadTail->next = temp;
           cyHeadTail = cyHeadTail->next;
           pTail = pTail->next;
        }
        RandomListNode*cpRandom(pHead);
        while (cpRandom)
        //利用原链表的random求得新链表的random
            map_node[cpRandom]->random = map_node[cpRandom->random];
            cpRandom = cpRandom->next;
        }
        return cyHead;
    }
};

int main(){
    Solution re;
    
    // 用来测试的链表
    RandomListNode node0(0);
    RandomListNode node1(1);
    RandomListNode node2(2);
    RandomListNode node3(3);
    RandomListNode node4(4);
    node0.next = &node1; node0.random = &node3;
    node1.next = &node2; node1.random = &node3;
    node2.next = &node3; node2.random = &node1;
    node3.next = &node4; node3.random = &node2;
    node4.next = nullptr;node4.random = &node1;
    RandomListNode* pHead = &node0;
    RandomListNode* result = re.Clone(pHead);
    cout << "-------------" << endl << "输入的链表: " << endl;
    while (pHead){
        if (pHead->next)
            cout << pHead->label << " 的下一个结点是: " << pHead->next->label << "   随机结点是: " << pHead->random->label<< endl;
        if (!pHead->next)
            cout << pHead->label << " 的下一个结点是:NULL"                       << " 随机结点是: " << pHead->random->label<< endl;
       pHead = pHead->next;
    }
    cout << endl << "-------------" << endl << "输出的链表: " << endl;
    while (result){
        if (result->next)
            cout << result->label << " 的下一个结点是: " << result->next->label << "   随机结点是: " << result->random->label << endl;
        if (!result->next)
            cout << result->label << " 的下一个结点是:NULL"                       << " 随机结点是: " << result->random->label<< endl;
        result = result->next;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值