剑指Offer----面试题26:复杂链表的复制

来源:互联网 发布:手机百度软件下载 编辑:程序博客网 时间:2024/05/27 09:47

题目:

请实现哈数ComplexListNode *Clone(ComplexListNode *pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个next指针指向下一个结点外,还有一个sibling指向链表的任意结点或者NULL。


分析:


如下图是一个含有5个结点的复杂链表,实箭头代表next指针,虚箭头代表sibling指针。指向NULL的指针没有画出。


第一步:根据原始链表的每个结点N创建对应的N‘,并把N’链接在N的后面。经过这一步,链表的形式如下图所示:


代码如下:
void CloneNode(ComplexListNode *pHead){ComplexListNode *node = pHead;while (node != NULL){ComplexListNode *copy = new ComplexListNode();copy->element = node->element;copy->next = node->next;node->next = copy;node = copy->next;}}

第二步:设置复制出来结点的sibling,假设原始链表上N的sibling指向结点S,那么其对应复制出来的N‘是N的next指向的结点,同样S’也是S的next指向的结点。经过这一步,链表的形式如下图所示:

代码如下:
void ConnectSibling(ComplexListNode *pHead){ComplexListNode *node = pHead;while (node != NULL){ComplexListNode *copy = node->next;if (node->sibling != NULL)copy->sibling = node->sibling->next;elsecopy->sibling = NULL;node = copy->next;}}

第三步:把这个长链表拆分成两个链表。把奇数位置的结点用next链接起来就是原始链表,把偶数为止的结点用next连接起来就是复制出来的链表。经过这一步,链表的形式如下图所示:

代码如下:
ComplexListNode *ReConnectNodes(ComplexListNode *pHead){ComplexListNode *node = pHead;ComplexListNode *copyHead = NULL;ComplexListNode *copyNode = NULL;if (node != NULL){copyHead = copyNode = node->next;//复制链表的头结点node->next = copyNode->next;node = node->next;}while (node != NULL){copyNode->next = node->next;copyNode = copyNode->next;node->next = copyHead->next;node = node->next;}return copyHead;}

最后将上面上面三步合在一起即可:

ComplexListNode *Clone(ComplexListNode *pHead){CloneNode(pHead);ConnectSibling(pHead);return ReConnectNodes(pHead);}

官方源代码(有改动):


头文件ComplexListNode.h
#ifndef COMPLEXLISTNODE_H#define COMPLEXLISTNODE_Hnamespace ComplexListNodeSpace{struct ComplexListNode{int element;ComplexListNode *next;ComplexListNode *sibling;};ComplexListNode *CreateComplexListNode(int value);void ConnectComplexListNode(ComplexListNode *root, ComplexListNode *pNext, ComplexListNode *pSibling);void printComplexList(ComplexListNode *root);void DestoryComplexList(ComplexListNode *root);}#endif

复杂链表实现文件ComplexListNode.cpp
#include"ComplexListNode.h"#include<iostream>using std::cout;using std::endl;namespace ComplexListNodeSpace{ComplexListNode *CreateComplexListNode(int value){ComplexListNode *temp = new ComplexListNode();temp->element = value;temp->next = NULL;temp->sibling = NULL;return temp;}void ConnectComplexListNode(ComplexListNode *root, ComplexListNode *pNext, ComplexListNode *pSibling){if (root == NULL)return;root->next = pNext;root->sibling = pSibling;}void printComplexList(ComplexListNode *root){if (root == NULL){cout << "The tree is empty" << endl;return;}ComplexListNode *temp = root;while (temp != NULL){cout << "The value of this node is " << temp->element << endl;if (temp->sibling != NULL)cout << "The sibling value of this node is " << temp->sibling->element << endl;elsecout << "The sibling of this node is NULL" << endl;temp = temp->next;}}void DestoryComplexList(ComplexListNode *root){if (root == NULL)return;ComplexListNode *temp = root;while (temp != NULL){root = root->next;delete temp;temp = root;}root = NULL;}}

测试文件:
#include"ComplexListNode.h"#include<cstdlib>#include<cstdio>using namespace ComplexListNodeSpace;void CloneNodes(ComplexListNode* pHead);void ConnectSiblingNodes(ComplexListNode* pHead);ComplexListNode* ReconnectNodes(ComplexListNode* pHead);ComplexListNode* Clone(ComplexListNode* pHead){CloneNodes(pHead);ConnectSiblingNodes(pHead);return ReconnectNodes(pHead);}void CloneNodes(ComplexListNode* pHead){ComplexListNode* pNode = pHead;while (pNode != NULL){ComplexListNode* pCloned = new ComplexListNode();pCloned->element = pNode->element;pCloned->next = pNode->next;pCloned->sibling = NULL;pNode->next = pCloned;pNode = pCloned->next;}}void ConnectSiblingNodes(ComplexListNode* pHead){ComplexListNode* pNode = pHead;while (pNode != NULL){ComplexListNode* pCloned = pNode->next;if (pNode->sibling != NULL){pCloned->sibling = pNode->sibling->next;}pNode = pCloned->next;}}ComplexListNode* ReconnectNodes(ComplexListNode* pHead){ComplexListNode* pNode = pHead;ComplexListNode* pClonedHead = NULL;ComplexListNode* pClonedNode = NULL;if (pNode != NULL){pClonedHead = pClonedNode = pNode->next;pNode->next = pClonedNode->next;pNode = pNode->next;}while (pNode != NULL){pClonedNode->next = pNode->next;pClonedNode = pClonedNode->next;pNode->next = pClonedNode->next;pNode = pNode->next;}return pClonedHead;}// ====================测试代码====================void Test(char* testName, ComplexListNode* pHead){if (testName != NULL)printf("%s begins:\n", testName);printf("The original list is:\n");printComplexList(pHead);ComplexListNode* pClonedHead = Clone(pHead);printf("======The cloned list is:\n");printComplexList(pClonedHead);}//          -----------------//         \|/              |//  1-------2-------3-------4-------5//  |       |      /|\             /|\//  --------+--------               |//          -------------------------void Test1(){printf("\t==============test1:普通==============\n");ComplexListNode* pNode1 = CreateComplexListNode(1);ComplexListNode* pNode2 = CreateComplexListNode(2);ComplexListNode* pNode3 = CreateComplexListNode(3);ComplexListNode* pNode4 = CreateComplexListNode(4);ComplexListNode* pNode5 = CreateComplexListNode(5);ConnectComplexListNode(pNode1, pNode2, pNode3);ConnectComplexListNode(pNode2, pNode3, pNode5);ConnectComplexListNode(pNode3, pNode4, NULL);ConnectComplexListNode(pNode4, pNode5, pNode2);Test("Test1", pNode1);DestoryComplexList(pNode1);}// m_pSibling指向结点自身//          -----------------//         \|/              |//  1-------2-------3-------4-------5//         |       | /|\           /|\//         |       | --             |//         |------------------------|void Test2(){printf("\t==============test2:sibliing指向结点自身==============\n");ComplexListNode* pNode1 = CreateComplexListNode(1);ComplexListNode* pNode2 = CreateComplexListNode(2);ComplexListNode* pNode3 = CreateComplexListNode(3);ComplexListNode* pNode4 = CreateComplexListNode(4);ComplexListNode* pNode5 = CreateComplexListNode(5);ConnectComplexListNode(pNode1, pNode2, NULL);ConnectComplexListNode(pNode2, pNode3, pNode5);ConnectComplexListNode(pNode3, pNode4, pNode3);ConnectComplexListNode(pNode4, pNode5, pNode2);Test("Test2", pNode1);DestoryComplexList(pNode1);}// m_pSibling形成环//          -----------------//         \|/              |//  1-------2-------3-------4-------5//          |              /|\//          |               |//          |---------------|void Test3(){printf("\t==============test3:sibling形成环==============\n");ComplexListNode* pNode1 = CreateComplexListNode(1);ComplexListNode* pNode2 = CreateComplexListNode(2);ComplexListNode* pNode3 = CreateComplexListNode(3);ComplexListNode* pNode4 = CreateComplexListNode(4);ComplexListNode* pNode5 = CreateComplexListNode(5);ConnectComplexListNode(pNode1, pNode2, NULL);ConnectComplexListNode(pNode2, pNode3, pNode4);ConnectComplexListNode(pNode3, pNode4, NULL);ConnectComplexListNode(pNode4, pNode5, pNode2);Test("Test3", pNode1);DestoryComplexList(pNode1);}// 只有一个结点void Test4(){printf("\t==============test4:只有一个结点==============\n");ComplexListNode* pNode1 = CreateComplexListNode(1);ConnectComplexListNode(pNode1, NULL, pNode1);Test("Test4", pNode1);DestoryComplexList(pNode1);}// 鲁棒性测试void Test5(){printf("\t==============test5:空链表==============\n");Test("Test5", NULL);}int main(){Test1();Test2();Test3();Test4();Test5();system("pause");return 0;}

运行结果:
        ==============test1:普通==============Test1 begins:The original list is:The value of this node is 1The sibling value of this node is 3The value of this node is 2The sibling value of this node is 5The value of this node is 3The sibling of this node is NULLThe value of this node is 4The sibling value of this node is 2The value of this node is 5The sibling of this node is NULL======The cloned list is:The value of this node is 1The sibling value of this node is 3The value of this node is 2The sibling value of this node is 5The value of this node is 3The sibling of this node is NULLThe value of this node is 4The sibling value of this node is 2The value of this node is 5The sibling of this node is NULL        ==============test2:sibliing指向结点自身==============Test2 begins:The original list is:The value of this node is 1The sibling of this node is NULLThe value of this node is 2The sibling value of this node is 5The value of this node is 3The sibling value of this node is 3The value of this node is 4The sibling value of this node is 2The value of this node is 5The sibling of this node is NULL======The cloned list is:The value of this node is 1The sibling of this node is NULLThe value of this node is 2The sibling value of this node is 5The value of this node is 3The sibling value of this node is 3The value of this node is 4The sibling value of this node is 2The value of this node is 5The sibling of this node is NULL        ==============test3:sibling形成环==============Test3 begins:The original list is:The value of this node is 1The sibling of this node is NULLThe value of this node is 2The sibling value of this node is 4The value of this node is 3The sibling of this node is NULLThe value of this node is 4The sibling value of this node is 2The value of this node is 5The sibling of this node is NULL======The cloned list is:The value of this node is 1The sibling of this node is NULLThe value of this node is 2The sibling value of this node is 4The value of this node is 3The sibling of this node is NULLThe value of this node is 4The sibling value of this node is 2The value of this node is 5The sibling of this node is NULL        ==============test4:只有一个结点==============Test4 begins:The original list is:The value of this node is 1The sibling value of this node is 1======The cloned list is:The value of this node is 1The sibling value of this node is 1        ==============test5:空链表==============Test5 begins:The original list is:The tree is empty======The cloned list is:The tree is empty请按任意键继续. . .



普通链表的复制:

#include"List.h"#include<iostream>using std::cout;using std::endl;using  namespace ListSpace4;ListNode *CopyList(ListNode *root){if (root == nullptr){cout << "链表为空,无法复制" << endl;return nullptr;}ListNode *prev = nullptr;ListNode *node = nullptr;ListNode *head = nullptr;int count = 0;while (root != nullptr){node = CreateListNode(root->element);++count;if (count == 1){head = node;}else{prev->next = node;}prev = node;node->next = nullptr;root = root->next;}return head;}void test41(){cout << "\t==========测试非空链表的复制==========" << endl;ListNode *list1 = CreateListNode(1);ListNode *list2 = CreateListNode(2);ListNode *list3 = CreateListNode(3);ListNode *list4 = CreateListNode(4);ListNode *list5 = CreateListNode(5);ListNode *list6 = CreateListNode(6);ConnectListNodes(list1, list2);ConnectListNodes(list2, list3);ConnectListNodes(list3, list4);ConnectListNodes(list4, list5);ConnectListNodes(list5, list6);ConnectListNodes(list6, NULL);cout << "复制链表之前:";printList(list1);cout << endl;cout << "复制链表之后:";ListNode *copy = CopyList(list1);printList(copy);cout << endl;DestoryList(&list1);DestoryList(&copy);}void test42(){cout << "\t==========测试只有一个结点的链表==========" << endl;ListNode *list1 = CreateListNode(1);ConnectListNodes(list1, NULL);cout << "复制之前表之前:";printList(list1);cout << endl;cout << "反转链表之后:";ListNode *copy = CopyList(list1);printList(copy);cout << endl;DestoryList(&list1);DestoryList(&copy);DestoryList(&list1);}void test43(){cout << "\t==========测试只有空链表==========" << endl;cout << "复制之前表之前:";printList(nullptr);cout << endl;cout << "反转链表之后:";ListNode *copy = CopyList(nullptr);printList(copy);cout << endl;}int main(){test41();cout << endl;test42();cout << endl;test43();cout << endl;system("pause");return 0;}

运行结果:
        ==========测试非空链表的复制==========复制链表之前:1  2  3  4  5  6复制链表之后:1  2  3  4  5  6        ==========测试只有一个结点的链表==========复制之前表之前:1反转链表之后:1        ==========测试只有空链表==========复制之前表之前:The list is empty反转链表之后:链表为空,无法复制The list is empty请按任意键继续. . .



0 0