复杂链表的复制 | 赋值链表

面试题26:复杂链表的复制

1.题目描述

请实现函数 ComplexListNode*Clone(ComplexListNode* pHead)复制一个复杂链表。在复杂链表中,每个结点除了有一个 m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL。结点的C++定义如下:

struct ComplexListNode
{
    int m_nValue;
    ComplexListNode* m_pNext;
    ComplexListNode8 m_pSibling;
};

2.题目分析

下图是一个含有5个结点的复杂链表。图中实线箭头表示 m_pNext指针,虚线箭头表示 m_Sibling指针。为简单起见,指向NULL的指针没有画出。

第一步是根据原始链表的每个结点N创建对应的N'。这时,我们把N'链接在N的后面。上图的链表经过这一步之后的结构,如下图所示。

完成这一步的代码如下:

void CloneNodes(ComplexListNode* pHead)
{
    ComplexListNode* pNode = pHead;
    while(pNode != NULL)
    {
        ComplexListNode* pCloned = new ComplexListNode();
        pCloned->m_nValue = pNode->m_nValue;
        pCloned->m_pNext = pNode->m_pNext;
        pCloned->m_pSibling = NULL;
        
        pNode->m_pNext = pCloned;
        pNode = pCloned->m_pNext;
    }
}

第二步设置复制出来的结点的 m_pSibling。假设原始链表上的N的m_pSibling指向结点S,那么其对应复制出来的N'是N的m_pNext指向的结点,同样S'也是S的m_pNext指向的结点。设置 m_pSibling之后的链表如下图所示。

下面是完成第二步的参考代码:

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

第三步把这个长链表拆分成两个链表:把奇数位置的结点用m_pNext链接起来就是原始链表,把偶数位置的结点用 m_pNext链接起来就是复制出来的链表。上图中的链表拆分之后的两个链表如下图所示。

要实现第三步的操作,也不是很难的事情。其对应的代码如下:

ComplexListNode* ReconnectNodes(ComplexListNode* pHead)
{
    ComplexListNode* pNode = pHead;
    ComplexListNode* pClonedHead = NULL;
    ComplexListNode* pClonedNode = NULL;
    
    if(pNode != NULL)
    {
        pClonedHead = pClonedNode = pNode->m_pNext;
        pNode->m_pNext = pClonedNode->m_pNext;
        pNode = pNode->m_pNext;
    }

    while(pNode != NULL)
    {
        pClonedNode->m_pNext = pNode->m_pNext;
        pClonedNOde = pClonedNode->m_pNext;
        pNode->m_pNext = pClonedNode->m_pNext;
        pNode = pNode->m_pNext;
    }
    return pClonedHead;
}

3.code

ComplexListNode* Clone(ComplexListNode* pHead)
{
    CloneNodes(pHead);
    ConnectSiblingNodes(pHead);
    return ReconnectNodes(pHead);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章