复制复杂的链表

在复杂链表中,每个节点除了有一个pNext指针指向下一个节点外,还有一个pSibling指向链表中的任意节点或者NULL.写一个函数

ComplexListNode* Clone(ComplexListNode* pHead),完成复制功能。

这里介绍一种在不使用辅助空间的情况下实现O(n)的时间效率的算法。

总共分为三步:第一步在每个节点N后面创业一个与之想对于的节点N'。让N指向N',而N‘则指向原来N指向的下一个节点。

如果原链表为A->B->C->D,则改变后为A->A'->B->B'->C->C'->D->D'

struct ComplexListNode
{
    int value;
    ComplexListNode* pNext;
    ComplexListNode* pSibling;
};

void CloneNode(ComplexListNode* pHead)
{
    ComplexListNode* pNode = pHead;
    while (pNode !=NULL)
    {
        ComplexListNode* pCloned = new ComplexListNode();
        pCloned->value = pNode->value;
        pCloned->pNext = pNode->pNext;
        pCloned->pSibling = pNode->pSibling;

        pNode->pNext = pCloned;
        pNode = pCloned->pNext;
    }
}

第二步:就是复制pSibling指针。让N‘的pSibling指针跟N的pSibling指针指向节点的下一个节点,如A有指针指向C的话则A'的pSibing应该指向C'。

代码如下:

void ConnectSiblingNodes(ComplexListNode* pHead)
{
    ComplexListNode* pNode =pHead;
    while( pNode != NULL)
    {
        ComplexListNode* pCloned = pNode->pNext;
        if( pNode->pSibling != NULL)
        {
            pCloned->pSibling = pNode->pSibling->pNext;
        }
        pNode = pCloned->pNext;
    }
}

第三步就是拆解,把节点N与N'分解开来。

ComplexListNode* ReconnectNodes(ComplexListNode* pHead)
{
    ComplexListNode* pNode = pHead;
    ComplexListNode* pClonedHead = NULL;
    ComplexListNode* pClonedNode = NULL;

    if( pNode != NULL)
    {
        pClonedHead = pClonedNode = pNode->pNext;
        pNode->pNext = pClonedNode->pNext;
        pNode = pNode->pNext;
    }

    while( pNode != NULL)
    {
        pClonedNode->pNext = pNode->pNext;
        pClonedNode = pNode->pNext;
        pNode->pNext = pClonedNode->pNext;
        pNode = pNode->pNext;
    }

    return pClonedHead;
}

//组合三个步骤
ComplexListNode* Clone(ComplexListNode* pHead)
{
    if(pHead == NULL)
        return NULL;
    CloneNode(pHead);
    ConnectSiblingNodes(pHead);
    return ReconnectNodes(pHead);
}

如果第三步不理解可以用画图来了解,就可以很简单的写出代码了。这题也很好的考察了对指针的运用功力

 

posted @ 2013-03-06 14:35  没离开过  阅读(108)  评论(0)    收藏  举报