題目:有一個復雜鏈表,其結點除了有一個m_pNext指針指向下一個結點外,還有一個m_pSibling指向鏈表中的任一結點或者NULL。其結點的C++定義如下:
1 struct ComplexNode 2 3 { 4 5 int m_nValue; 6 7 ComplexNode* m_pNext; 8 9 ComplexNode* m_pSibling; 10 11 };
請完成函數ComplexNode* Clone(ComplexNode* pHead),以復制一個復雜鏈表。
思路:分三步,在不用輔助空間的情況下實現O(n)的時間效率。第一步,復制原始鏈表的任意結點N並創建新結點N‘,再把N’鏈接到N的後面
第二步,如果原始鏈表的結點N的m_pSibling指向S,則它對應的復制結點N‘的m_pSibling指向S的下一結點S’
第三步,把這個鏈表拆分成兩個鏈表
1 #include<stdio.h> 2 #include<iostream> 3 #include "stdafx.h" 4 5 struct ComplexListNode 6 { 7 int m_nValue; 8 ComplexListNode* m_pNext; 9 ComplexListNode* m_pSibling; 10 }; 11 12 ComplexListNode* CreateNode(int nValue); 13 void BuildNodes(ComplexListNode* pNode, ComplexListNode* pNext, ComplexListNode* pSibling); 14 void PrintList(ComplexListNode* pHead); 15 16 ComplexListNode* CreateNode(int nValue) 17 { 18 ComplexListNode* pNode = new ComplexListNode(); 19 20 pNode->m_nValue = nValue; 21 pNode->m_pNext = NULL; 22 pNode->m_pSibling = NULL; 23 24 return pNode; 25 } 26 27 void BuildNodes(ComplexListNode* pNode, ComplexListNode* pNext, ComplexListNode* pSibling) 28 { 29 if(pNode != NULL) 30 { 31 pNode->m_pNext = pNext; 32 pNode->m_pSibling = pSibling; 33 } 34 } 35 36 void PrintList(ComplexListNode* pHead) 37 { 38 ComplexListNode* pNode = pHead; 39 while(pNode != NULL) 40 { 41 printf("The value of this node is: %d.\n", pNode->m_nValue); 42 43 if(pNode->m_pSibling != NULL) 44 printf("The value of its sibling is: %d.\n", pNode->m_pSibling->m_nValue); 45 else 46 printf("This node does not have a sibling.\n"); 47 48 printf("\n"); 49 50 pNode = pNode->m_pNext; 51 } 52 } 53 54 void CloneNodes(ComplexListNode* pHead); //復制原始鏈表 55 void ConnectSiblingNodes(ComplexListNode* pHead); //設置復制出來的的結點的m_pSibling 56 ComplexListNode* ReconnectNodes(ComplexListNode* pHead);//拆分兩個鏈表 57 58 ComplexListNode* Clone(ComplexListNode* pHead) 59 { 60 CloneNodes(pHead); 61 ConnectSiblingNodes(pHead); 62 return ReconnectNodes(pHead); 63 } 64 65 //第一步 66 void CloneNodes(ComplexListNode* pHead) 67 { 68 ComplexListNode* pNode = pHead; 69 while(pNode != NULL) 70 { 71 ComplexListNode* pCloned = new ComplexListNode(); 72 pCloned->m_nValue = pNode->m_nValue; 73 pCloned->m_pNext = pNode->m_pNext; 74 pCloned->m_pSibling = NULL; 75 76 pNode->m_pNext = pCloned; 77 78 pNode = pCloned->m_pNext; 79 } 80 } 81 82 //第二步 83 void ConnectSiblingNodes(ComplexListNode* pHead) 84 { 85 ComplexListNode* pNode = pHead; 86 while(pNode != NULL) 87 { 88 ComplexListNode* pCloned = pNode->m_pNext; 89 if(pNode->m_pSibling != NULL) 90 { 91 pCloned->m_pSibling = pNode->m_pSibling->m_pNext; 92 } 93 94 pNode = pCloned->m_pNext; 95 } 96 } 97 98 //第三步 99 ComplexListNode* ReconnectNodes(ComplexListNode* pHead) 100 { 101 ComplexListNode* pNode = pHead; 102 ComplexListNode* pClonedHead = NULL; 103 ComplexListNode* pClonedNode = NULL; 104 105 if(pNode != NULL) 106 { 107 pClonedHead = pClonedNode = pNode->m_pNext; 108 pNode->m_pNext = pClonedNode->m_pNext; 109 pNode = pNode->m_pNext; 110 } 111 112 while(pNode != NULL) 113 { 114 pClonedNode->m_pNext = pNode->m_pNext; 115 pClonedNode = pClonedNode->m_pNext; 116 117 pNode->m_pNext = pClonedNode->m_pNext; 118 pNode = pNode->m_pNext; 119 } 120 121 return pClonedHead; 122 } 123 124 // ----------------- 125 // \|/ | 126 // 1-------2-------3-------4-------5 127 // | | /|\ /|\ 128 // --------+-------- | 129 // ------------------------- 130 131 int main() 132 { 133 ComplexListNode* pNode1 = CreateNode(1); 134 ComplexListNode* pNode2 = CreateNode(2); 135 ComplexListNode* pNode3 = CreateNode(3); 136 ComplexListNode* pNode4 = CreateNode(4); 137 ComplexListNode* pNode5 = CreateNode(5); 138 139 BuildNodes(pNode1, pNode2, pNode3); 140 BuildNodes(pNode2, pNode3, pNode4); 141 BuildNodes(pNode3, pNode4, NULL); 142 BuildNodes(pNode4, pNode5, pNode2); 143 144 printf("The original list is:\n"); 145 PrintList(pNode1); 146 147 ComplexListNode* pClonedHead = Clone(pNode1); 148 149 printf("The cloned list is:\n"); 150 PrintList(pClonedHead); 151 }