复杂链表
- sibling链表:链表的节点信息,除了next的指向以外,还有sibling的指向。请复制该链表。
- 带环链表:一个单链表(带环),如何找到环的入口点。
- 环形链表:0、1...n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第n个数字。求这个圆圈里剩下的最后一个数字。
- 双向链表:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
1、思路:
参见剑指offer的26题
CloneNodes
1 ComplexListNode* Clone(ComplexListNode* pHead) 2 { 3 CloneNodes(pHead); 4 ConnectSiblingNodes(pHead); 5 return ReconnectNodes(pHead); 6 } 7 8 void CloneNodes(ComplexListNode* pHead) 9 { 10 ComplexListNode* pNode = pHead; 11 while(pNode != NULL) 12 { 13 ComplexListNode* pCloned = new ComplexListNode(); 14 pCloned->m_nValue = pNode->m_nValue; 15 pCloned->m_pNext = pNode->m_pNext; 16 pCloned->m_pSibling = NULL; 17 18 pNode->m_pNext = pCloned; 19 20 pNode = pCloned->m_pNext; 21 } 22 } 23 24 void ConnectSiblingNodes(ComplexListNode* pHead) 25 { 26 ComplexListNode* pNode = pHead; 27 while(pNode != NULL) 28 { 29 ComplexListNode* pCloned = pNode->m_pNext; 30 if(pNode->m_pSibling != NULL) 31 { 32 pCloned->m_pSibling = pNode->m_pSibling->m_pNext; 33 } 34 35 pNode = pCloned->m_pNext; 36 } 37 } 38 39 ComplexListNode* ReconnectNodes(ComplexListNode* pHead) 40 { 41 ComplexListNode* pNode = pHead; 42 ComplexListNode* pClonedHead = NULL; 43 ComplexListNode* pClonedNode = NULL; 44 45 if(pNode != NULL) 46 { 47 pClonedHead = pClonedNode = pNode->m_pNext; 48 pNode->m_pNext = pClonedNode->m_pNext; 49 pNode = pNode->m_pNext; 50 } 51 52 while(pNode != NULL) 53 { 54 pClonedNode->m_pNext = pNode->m_pNext; 55 pClonedNode = pClonedNode->m_pNext; 56 57 pNode->m_pNext = pClonedNode->m_pNext; 58 pNode = pNode->m_pNext; 59 } 60 61 return pClonedHead; 62 }
2、思路:
设置一个slow指针和一个fast指针,slow每次走一步,fast每次走两步,则两个指针必然会在环中相遇。假设slow走了s步,则fast就走了2s步;另外假设起始点距离入口点为x步,环长r步,链长L=(x+r)步;还有假设入口点距离相遇点为y步。
若fast和slow相遇,则slow必然没有遍历完环形链表,那么2s=s+nr,得s=nr;而且x+y=s,那么x+y=nr=(n-1)r+r=(n-1)r+L-x,得x=(n-1)r+(r-y)。说明从起始点和相遇点同时出发,第一次相遇点就是入口点。
FindLoopPort
1 slist* FindLoopPort(slist *head) 2 { 3 slist *slow = head, *fast = head; 4 5 while ( fast && fast->next ) 6 { 7 slow = slow->next; 8 fast = fast->next->next; 9 if ( slow == fast ) break; 10 } 11 12 if (fast == NULL || fast->next == NULL) 13 return NULL; 14 15 slow = head; 16 while (slow != fast) 17 { 18 slow = slow->next; 19 fast = fast->next; 20 } 21 22 return slow; 23 }