什么是复杂链表???
如图,这是一个复杂链表,每个结点包含两个指针域,其中next指针域相互连接构成一个单链表,而另一个指针域Sibling则随意指向链表中的任意位置,或者指向NULL。
复制复杂链表!!!
实现这个问题的方法比较多,下面来介绍三种方法。。
方法一:
新建一个头结点,先不考虑Sibling,将整个单链表复制一份。然后寻找每个结点的Sibling所指向的位置。以寻找2这个结点的Sibling为例:设置一个计步器count,然后以游标指针cur遍历整个链表,如果cur的地址等于2这个结点的Sibling,则寻找成功,这时在新链表中走上count步所找到的结点就是我们要找的结点。这个方法效率最低。
代码如下:
pLinkNode CloneComplexLinklist(pLinkNode head)
{
pLinkNode cur = head->next;
if (NULL == head->next) //判断是不是空链表
{
return NULL;
}
pLinkNode newNode= NULL;
pLinkNode newhead = NULL;
CreateNode(&newhead, cur->data);
pLinkNode last= newhead; //新建一个头结点
cur = cur->next;
while (NULL != cur) //复制整个链表
{
CreateNode(&newNode, cur->data);
last->next = newNode;
cur = cur->next;
last = last->next;
}
cur = head->next;
pLinkNode p = newhead;
int s = 0; //计步器
//链接Sibling
while (NULL != cur)
{
last = head->next;
while (cur->Sibling&&cur->Sibling != last) //找到当前结点cur的Sibling在旧链表中的位置
{
s++;
last = last->next;
}
//如果这个位置不为空
if (NULL != cur->Sibling)
{
last=newhead;
while (s>0) //寻找cur所对应结点p的Sibling在新链表中的位置
{
s--;
last=last->next;
}
p->Sibling = last; //链接p的Sibling
}
cur = cur->next;
p = p->next;
}
return newhead; //返回头结点
}
方法二:
利用哈希表,在复制新链表的同时我们将新旧结点<N,N'>的关系保存下来,这时我们就能在O(1)的时间内通过N的Sibling找到N'的Sibling。这个方法已经很高了,但是却有O(n)的空间耗费。
方法三:
同方法一一样先复制一个单链表,不同的是这次每复制一个结点都将它链接到原结点后面,如图:
//复制新的结点链接在原来结点后面
void CopyLinkNode(pLinkNode head)
{
pLinkNode cur = head->next;
pLinkNode newNode = NULL;
while (NULL != cur)
{
CreateNode(&newNode,cur->data); //新建结点newNode
newNode->next = cur->next; //将这个结点链接到当前结点的后面
cur->next = newNode;
cur = newNode->next;
}
}
接下来设置新节点的Sibling。例如要设置1’的Sibling,只需让1’的Sibling指向1的Sibling的next就可以了,还要注意1的Sibling要不为NULL才行。
//链接新建结点的Sibling指针
void ConnectSiblingNode(pLinkNode head)
{
pLinkNode cur = head->next;
pLinkNode tail = NULL;
while (NULL!=cur)
{
tail = cur->next;
tail->Sibling = cur->Sibling; //tail指针的Sibling指cur的Sibling的位置
if (NULL != tail->Sibling) //如果tail的Sibling指针不空,值链接新节点的Sibling
{
tail->Sibling = tail->Sibling->next;
}
cur = tail->next;
}
}
最后一步将两个链表拆分开就可以了。
//拆分两个链表
pLinkNode SeparateLinkList(pLinkNode head)
{
if (NULL == head->next)
{
return NULL;
}
pLinkNode newhead =head->next->next; //指向新链表的的指针
pLinkNode last =newhead;
pLinkNode cur = newhead->next;
head->next->next = cur;
while (NULL!=cur) //拆分这个链表
{
last->next = cur->next;
last = last->next;
cur->next =last->next;
cur = cur->next;
}
return newhead; //返回新链表的地址
}
将上面三个函数封装成一个函数
//复制复杂链表
pLinkNode CloneComplexLinklist(pLinkNode head)
{
pLinkNode newlist = NULL;
CopyLinkNode(head); //复制新的结点链接在原来结点后面
ConnectSiblingNode(head); //链接新建结点的Sibling指针
newlist=SeparateLinkList(head); //拆分链表
return newlist;
}