剑指Offer-26-复杂链表的复制

题目:
有一个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任一结点或者NULL。其结点的C++定义如下:
struct ComplexNode
{
int m_nValue;
ComplexNode* m_pNext;
ComplexNode* m_pSibling;
};
这里写图片描述
请完成函数ComplexNode* Clone(ComplexNode* pHead),以复制一个复杂链表。

第一种方法:
分成两步:第一步是复制原始链表上的每个链表,并用m_pNext链接起来。第二步,假设原始链表中的某节点N的m_pSibling指向结点S。由于S的位置在链表上有可能在N的前面也可能在N的后面,所以要定位N的位置我们需要从原始链表的头结点开始找。假设从原始链表的头结点开始经过s步找到结点S。那么在复制链表上结点N的m_pSibling的S’,离复制链表的头结点的距离也是s。用这种办法我们就能为复制链表上的每个结点设置m_pSibling了。
对一个含有n个结点的链表,由于定位每个结点的m_pSibling,都需要从链表头结点开始经过O(n)步才能找到,因此这种方法的总时间复杂度是O(n2)。

下一篇将使用o(n)复杂度的算法,实现该功能。

#include <iostream>
using namespace std;

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

/**
 * 使用一般方式进行复制,时间复杂度o(n*n)
 */
ComplexListNode* clone(ComplexListNode *pHead) {
    if(pHead == NULL)
        return NULL;
    ComplexListNode *pNewHead = new ComplexListNode();
    pNewHead->m_nValue = pHead->m_nValue;
    pNewHead->m_pNext = NULL;
    pNewHead->m_pSibling = NULL;

    ComplexListNode *p = pHead->m_pNext;
    ComplexListNode *preNewP = pNewHead;

    //第一步:复制原始链表的每一个结点,按照p->m_pNext连接起来
    while(p) {
        ComplexListNode *newP = new ComplexListNode();
        newP->m_nValue = p->m_nValue;
        newP->m_pNext = NULL;
        newP->m_pSibling = NULL;

        preNewP->m_pNext = newP;
        preNewP = newP;

        p=p->m_pNext;
    }

    p = pHead;
    ComplexListNode *newp = pNewHead;
    //第二步:设置每个结点的m_pSibling指针
    //如果原始链表的头结点开始沿着m_pNext经过s步找到结点S,那么复制链表上结点N的N'的m_pSibling(S')
    //离复制链表的头结点的距离也是沿着m_pNext指针s步。
    while(p) {
        if(p->m_pSibling != NULL) {
            ComplexListNode *sibling = pHead;
            ComplexListNode *newSibling = pNewHead;
            while(sibling != p->m_pSibling) {
                sibling = sibling->m_pNext;
                newSibling = newSibling->m_pNext;
            }
            newp->m_pSibling = newSibling;
        }
        p = p->m_pNext;
        newp = newp->m_pNext;
    }
    return pNewHead;
}



ComplexListNode* CreateNode(int nValue)
{
    ComplexListNode* pNode = new ComplexListNode();

    pNode->m_nValue = nValue;
    pNode->m_pNext = NULL;
    pNode->m_pSibling = NULL;

    return pNode;
}

void BuildNodes(ComplexListNode* pNode, ComplexListNode* pNext, ComplexListNode* pSibling)
{
    if(pNode != NULL)
    {
        pNode->m_pNext = pNext;
        pNode->m_pSibling = pSibling;
    }
}

void PrintList(ComplexListNode* pHead)
{
    ComplexListNode* pNode = pHead;
    while(pNode != NULL)
    {
        cout<<"The value of this node is:"<<pNode->m_nValue<<".";

        if(pNode->m_pSibling != NULL)
            cout<<"The value of its sibling is:"<<pNode->m_pSibling->m_nValue<<".";
        else
            cout<<"This node does not have a sibling.";

        cout<<endl;

        pNode = pNode->m_pNext;
    }
}

// ====================测试代码====================
void Test(char* testName, ComplexListNode* pHead)
{
    if(testName != NULL)
        cout<<testName;

    cout<<"The original list is:"<<endl;
    PrintList(pHead);

    ComplexListNode* pClonedHead = clone(pHead);

    cout<<"The cloned list is:"<<endl;
    PrintList(pClonedHead);
}

//          -----------------
//         \|/              |
//  1-------2-------3-------4-------5
//  |       |      /|\             /|\
//  --------+--------               |
//          -------------------------
void Test1()
{
    ComplexListNode* pNode1 = CreateNode(1);
    ComplexListNode* pNode2 = CreateNode(2);
    ComplexListNode* pNode3 = CreateNode(3);
    ComplexListNode* pNode4 = CreateNode(4);
    ComplexListNode* pNode5 = CreateNode(5);

    BuildNodes(pNode1, pNode2, pNode3);
    BuildNodes(pNode2, pNode3, pNode5);
    BuildNodes(pNode3, pNode4, NULL);
    BuildNodes(pNode4, pNode5, pNode2);

    Test("Test1", pNode1);
}

// m_pSibling指向结点自身
//          -----------------
//         \|/              |
//  1-------2-------3-------4-------5
//         |       | /|\           /|\
//         |       | --             |
//         |------------------------|
void Test2()
{
    ComplexListNode* pNode1 = CreateNode(1);
    ComplexListNode* pNode2 = CreateNode(2);
    ComplexListNode* pNode3 = CreateNode(3);
    ComplexListNode* pNode4 = CreateNode(4);
    ComplexListNode* pNode5 = CreateNode(5);

    BuildNodes(pNode1, pNode2, NULL);
    BuildNodes(pNode2, pNode3, pNode5);
    BuildNodes(pNode3, pNode4, pNode3);
    BuildNodes(pNode4, pNode5, pNode2);

    Test("Test2", pNode1);
}

// m_pSibling形成环
//          -----------------
//         \|/              |
//  1-------2-------3-------4-------5
//          |              /|\
//          |               |
//          |---------------|
void Test3()
{
    ComplexListNode* pNode1 = CreateNode(1);
    ComplexListNode* pNode2 = CreateNode(2);
    ComplexListNode* pNode3 = CreateNode(3);
    ComplexListNode* pNode4 = CreateNode(4);
    ComplexListNode* pNode5 = CreateNode(5);

    BuildNodes(pNode1, pNode2, NULL);
    BuildNodes(pNode2, pNode3, pNode4);
    BuildNodes(pNode3, pNode4, NULL);
    BuildNodes(pNode4, pNode5, pNode2);

    Test("Test3", pNode1);
}

// 只有一个结点
void Test4()
{
    ComplexListNode* pNode1 = CreateNode(1);
    BuildNodes(pNode1, NULL, pNode1);

    Test("Test4", pNode1);
}

// 鲁棒性测试
void Test5()
{
    Test("Test5", NULL);
}

int main() {
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值