複雜鏈表的複製 | 賦值鏈表

面試題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);
}

 

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