复杂链表

  1. sibling链表:链表的节点信息,除了next的指向以外,还有sibling的指向。请复制该链表。
  2. 带环链表:一个单链表(带环),如何找到环的入口点。
  3. 环形链表:0、1...n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第n个数字。求这个圆圈里剩下的最后一个数字。
  4. 双向链表:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。

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   }

 

 

 

 

posted on 2013-04-14 16:39  月moon鸟  阅读(190)  评论(0编辑  收藏  举报

导航