,,首先我们先来看一下复杂链表的结构:
随机
,,,
,headheadrandom才能+ +随机———随机
randomrandomrandom
比较方案一与方案二:我们将会发现方案一的空间复杂度小,实现比较简单。方案二的空间复杂度大,代码比较冗余,但容易想到。
下面我们来看一下他们各自的代码:
方案一:
ComplexList *, Listcpy2 (ComplexList *, cl) { Node*,坏蛋=cl→_head;//复制链表 而(坏蛋) { Node *, tmp=new 节点(cur→_data); tmp→_next=cur→_next; 坏蛋→_next=tmp; 坏蛋=tmp→_next; } 坏蛋=cl→_head;//置它的随机的 而(坏蛋) { 如果(cur→_random !=NULL) { Node *,接下来=cur→_next; 下→_random=cur→_random→_next; 坏蛋=cur→_next→_next; } } 坏蛋=cl→_head; Node *, newhead=零; Node *, newtail=零;//将奇偶位置的节点拆分成两个链表 如果(坏蛋)//置头结点和尾节点 { newhead=newtail=cur→_next; 坏蛋→_next=newhead→_next; 坏蛋=cur→_next; } 而(坏蛋) { newtail→_next=cur→_next; newtail=newtail→_next; 坏蛋→_next=newtail→_next; 坏蛋=cur→_next; } return newhead; }
方案二:
ComplexList&, ListCpy (ComplexList&, cl) {,, Node*,坏蛋=cl._head; ,,,Node *, cur1=_head; 而(cur→_next !=NULL) { cur1→_data=https://www.yisu.com/zixun/cur-> _data; cur1 -> _next=cur -> _next; 如果(cur -> _random==NULL) { cur1 -> _random=零; } 其他的 { 节点 * cur4=坏蛋; int数=1; cur4=cur -> _next;//遍历找出C1当前节点的随机指针指向的位置,并用一个计数//器记录遍历的次数 而(cur -> _random !=cur4) { 如果(cur4 -> _next==NULL) { cur4 -> _next=_head; 数+ +; } 其他的 { 数+ +; } cur4=cur4 -> _next; }//通过对计数器的,找到这当前节点随机的指针位置,并//赋值 节点 * cur2=cur1; 而(计数) { cur2=cur2 -> _next; 如果(cur2==NULL) { cur2=_head; } 数, } cur1 -> _random=cur2; }//让当前指针指向下一个位置 坏蛋=cur -> _next; cur1=cur1 -> _next;//在上面的代码中,我们有可能改掉了C1的最后一个节点的接下来,让它指向//了第一个节点,所以此处将其的下重新置空,否则整个链表将会变成循//环链表 如果(cur -> _next==_head) { 坏蛋-> _next=零; } } 返回*; }
最后博主再来讲一个函数,是将链表节点的随机指针指向位置的函数,也就是设置随机的函数
void SetRandom (ComplexList&, cl, int n=1, int count=0)//这里的参数n的表示相对头节点有几个位//置的节点,也就是我们要设置的节点.count表示相对设置的节点的位置即相对位置的节点向后指向//次,找到随机的位置。 { Node*, cur1=_head; 如果(n==1 | |数==0) { 返回; } 而(n——) { cur1=cur1→_next; } Node *, cur2=cur1; 而(计数) { 如果(cur2→_next==NULL) { cur2=_head; } 其他的 { cur2=cur2→_next; } } cur1→_random=cur2; }