在复杂链表中不仅有一个指向下一个节点的_next 域还有一个随机域_rand
在复杂链表的复制中我们可以先将随机域全部置NULL其他节点复制下来
然后定义一个计数器每次进入前将其置零记录源链表的随机域指向第N个节点之后将目标链表对应节点的随机域指向目标的第N个节点
pList Get(int data)
{
pList ptmp = (pList)malloc(sizeof(List));
if (NULL == ptmp)
{
exit(1);
}
ptmp->_data = data;
ptmp->_next = NULL;
ptmp->_rand = NULL;
return ptmp;
}
void Push(pList pH,int data)
{
pList ptmp = pH;
if (NULL == pH)
{
return;
}
while (ptmp->_next)
{
ptmp = ptmp->_next;
}
ptmp->_next = Get(data);
}
pList CopyComplexList(pList pH)
{
pList ptmp = pH;
pList ptmp1 = pH;
pList pNode = NULL;
pList pN;
if (NULL == pH)
{
return NULL;
}
pNode = Get(ptmp->_data);
ptmp = ptmp->_next;
while (ptmp)
{
Push(pNode,ptmp->_data);
ptmp = ptmp->_next;
}
ptmp = pH;
pN = pNode;
while (ptmp)
{
int count = 0;
pList pN1 = pNode;
ptmp1 = pH;
if (ptmp->_rand == NULL) /*源链表中某个节点的随机域指向NULL直接将目标链表对应的节点的随机域置为NULL结束本次循环*/
{
pN->_rand = NULL;
ptmp = ptmp->_next;
pN = pN->_next;
continue;
}
while (ptmp1&&(ptmp1 != ptmp->_rand)) /*遍历链表找出当前链表随机域是第count个结点*/
{
count++;
ptmp1 = ptmp1->_next;
}
while (count--&&pN1)/*对应节点的随机域指向第count个结点*/
{
pN1 = pN1->_next;
}
pN->_rand = pN1;
pN = pN->_next;
ptmp = ptmp->_next;
}
return pNode;
}
这个算法的时间复杂度为O(n^2)
下面这种算法的时间复杂度为O(N)
typedef struct ComplexList
{
int _data;
struct ComplexList* _next;
struct ComplexList* _rand;
}ComplexList, *pComplexList;
pComplexList Get(int data)
{
pComplexList ptmp = (pComplexList)malloc(sizeof(ComplexList));
if (NULL == ptmp)
{
exit(1);
}
ptmp->_data = data;
ptmp->_next = NULL;
ptmp->_rand = NULL;
return ptmp;
}
void Push(pComplexList* pH, int data)
{
pComplexList ptmp = NULL;
assert(pH);
ptmp = *pH;
if (NULL == ptmp)
{
*pH = Get(data);
return;
}
while (ptmp->_next)
{
ptmp = ptmp->_next;
}
ptmp->_next = Get(data);
}
void Destory(pComplexList* pHead)
{
pComplexList pcur = NULL;
assert(pHead);
pcur = *pHead;
while (pcur)
{
pComplexList ptmp = pcur;
pcur = pcur->_next;
free(ptmp);
}
*pHead = NULL;
}
pComplexList Find(pComplexList pH, int data)
{
while (pH)
{
if (data == pH->_data)
return pH;
pH = pH->_next;
}
return NULL;
}
void MakeComplexList(pComplexList* pH)
{
assert(pH);
Push(pH, 1);
Push(pH, 2);
Push(pH, 3);
Push(pH, 4);
Push(pH, 5);
Push(pH, 6);
pComplexList ptmp = *pH;
ptmp->_rand = Find(*pH, 3);//1
ptmp = ptmp->_next;
ptmp->_rand = Find(*pH, 6);//2
ptmp = ptmp->_next;
ptmp->_rand = Find(*pH, 1); //3
ptmp = ptmp->_next;
ptmp->_rand = Find(*pH, 0);//4
ptmp = ptmp->_next;
ptmp->_rand = Find(*pH, 5);//5
ptmp = ptmp->_next;
ptmp->_rand = Find(*pH, 3);//6
}
pComplexList CopyComplexList(pComplexList pH)
{
pComplexList pNewHead = NULL;
if (pH)
{
pComplexList pcur = pH;
pComplexList ptmp = NULL;
while (pcur)
{
ptmp = Get(pcur->_data);
ptmp->_next = pcur->_next;
pcur->_next = ptmp;
pcur = ptmp->_next;
}
pcur = pH;
while (pcur && pcur->_next)
{
ptmp = pcur->_next;
if (pcur->_rand)
ptmp->_rand = pcur->_rand->_next;
pcur = ptmp->_next;
}
pcur = pH;
pNewHead = pcur->_next;
ptmp = pNewHead;
while (pcur)
{
ptmp = pcur->_next;
pcur->_next = ptmp->_next;
pcur = pcur->_next;
if (pcur)
ptmp = pcur->_next;
}
}
return pNewHead;
}