复杂链表的复制

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

结点结构体以下:dom

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

这是一道剑指offer上的题目。下面看一下解析吧。spa

在作这道题以前,本身的想法是先把链表中的next域所有复制,这时候原复杂链表的random域的全部指向都会存在于刚才复制的链表中,以后再遍历原复杂链表,将新链表random域与原链表random域相互对应便可。.net

可是过程当中问题就出现了,虽然我能够在将原链表的全部next域所有复制,也保证了即将要复制的random域的指向存在于该链表中,可是random域是随机指的,也就是说并不知道当前的random域指向的结点在前面仍是后面,如此一来,若是还要继续下去,恐怕还要嵌套一层循环。指针

为此,又在网上找了大神的博客参考下,真的是受益不浅。code

想一想咱们平时复制粘贴一段文字的时候是怎么作的?是照着那段文字一个一个的再敲一次吗?并非,很显然,咱们是直接在该段文字上复制,而后将复制后的文字粘贴到咱们想要的地方。htm

上面的笨办法显然就是一个一个的再敲一个链表出来,并无作真正的复制blog

那怎么作?对,就是直接在原链表上复制一份链表,最后将咱们想要的备份链表从原链表中抽离出来。get

具体分三个步骤:博客

1.再原链表的每一个结点后面插入一个与当前结点数据域相同的结点

2.复制random域的对应关系

3.抽离链表

完整代码以下

RandomListNode* Clone(RandomListNode* pHead) { if(!pHead){ return NULL; } RandomListNode *head = NULL; RandomListNode *p, *pf = NULL; RandomListNode *q; // 先复制结点
        for(p = pHead; p; p = p->next->next){ q = new RandomListNode(p->label); q->next = p->next; p->next = q; } // 复制random域对应关系
        for(p = pHead; p; p = p->next->next){ if(!p->random){ p->next->random = p->random; }else{ p->next->random = p->random->next; } } //抽离链表
        head = pHead->next; for(p = pHead, q = head; q; q = q->next){ p->next = p->next->next; if(q->next){ p = p->next; q->next = q->next->next; } } return head; }

下面附一下参考连接,上面有图,更容易理解。

http://www.javashuo.com/article/p-kducekdg-ky.html

end。

原文出处:https://www.cnblogs.com/GuoYuying/p/11478469.html

相关文章
相关标签/搜索