首先我们先来看一下复杂链表的结构:
成都创新互联公司是专业的普陀网站建设公司,普陀接单;提供网站建设、成都网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行普陀网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!这个链表不能直接进行复制,如果我们对其进行直接复制将会发现复制后的链表的random依旧指向之前链表的位置,并没有指向自身的某个节点。因此,我们需要好好分析一下。
方案一:
我们可以一个节点一个节点的进行复制,并将复制后的节点放到原节点的后边。这样就形成了一个这样的链表:
然后我们将复制后的节点指向原节点random指针指向的位置的下一个位置,遍历完整个链表。接下来最重要的是将链表按照奇偶的不同拆分为两个独立的链表便可等到与原链表一样的链表。
方案二:
我们首先让当前位置指向head,然后判断head的random是否为空,如果为空直接复制,若不为空,则需要先记住当前节点,然后向后遍历,引入计数器,遍历一次计数器++;直到找到与random相等的节点,然后将你要复制的链表的当前位置以计数器--,向后遍历,找到之后将记住的当前节点的random指向找到的节点。依次遍历即可。
如果要将random指向自身的某个节点,我们需要记录random与random指向节点
比较方案一与方案二:我们将会发现方案一的空间复杂度小,实现比较简单。方案二的空间复杂度大,代码比较冗余,但容易想到。
下面我们来看一下他们各自的代码:
方案一:
ComplexList* Listcpy2(ComplexList* cl) { Node* cur=cl->_head; //复制链表 while(cur) { Node * tmp=new Node(cur->_data); tmp->_next=cur->_next; cur->_next=tmp; cur=tmp->_next; } cur=cl->_head; //置它的random while(cur) { if(cur->_random!=NULL) { Node * next=cur->_next; next->_random=cur->_random->_next; cur=cur->_next->_next; } } cur=cl->_head; Node * newhead=NULL; Node * newtail=NULL; //将奇偶位置的节点拆分成两个链表 if(cur)//置头结点和尾节点 { newhead=newtail=cur->_next; cur->_next=newhead->_next; cur=cur->_next; } while(cur) { newtail->_next=cur->_next; newtail=newtail->_next; cur->_next=newtail->_next; cur=cur->_next; } return newhead; }
方案二:
ComplexList& ListCpy(ComplexList& cl) { Node* cur=cl._head; Node * cur1=_head; while(cur->_next!=NULL) { cur1->_data=cur->_data; cur1->_next=cur->_next; if(cur->_random==NULL) { cur1->_random=NULL; } else { Node * cur4=cur; int count=1; cur4=cur->_next; //遍历找出C1当前节点的random指针指向的位置,并用一个计数 //器记录遍历的次数 while(cur->_random!=cur4) { if(cur4->_next==NULL) { cur4->_next=_head; count++; } else { count++; } cur4=cur4->_next; } //通过对计数器的--;找到this当前节点random的指针位置,并 //赋值 Node * cur2=cur1; while(count) { cur2=cur2->_next; if(cur2==NULL) { cur2=_head; } count--; } cur1->_random=cur2; } //让当前指针指向下一个位置 cur=cur->_next; cur1=cur1->_next; //在上面的代码中,我们有可能改掉了C1的最后一个节点的next,让它指向 //了第一个节点,所以此处将其的next重新置空,否则整个链表将会变成循 //环链表 if(cur->_next==_head) { cur->_next=NULL; } } return *this; }
最后博主再来讲一个函数,是将链表节点的random指针指向位置的函数,也就是设置random的函数
void SetRandom(ComplexList& cl,int n=-1,int count=0)//这里的参数n的表示相对头节点有几个位//置的节点,也就是我们要设置的节点。count表示相对设置的节点的位置即相对位置的节点向后指向//count次,找到random的位置。 { Node* cur1=_head; if(n==-1||count==0) { return; } while(n--) { cur1=cur1->_next; } Node * cur2=cur1; while(count--) { if(cur2->_next==NULL) { cur2=_head; } else { cur2=cur2->_next; } } cur1->_random=cur2; }
创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。