找到循环链表的入口节点
2015-08-14 11:45
483 查看
一个链表中包含环,请找出该链表的环的入口结点。
#include <iostream> #include "List.h" using namespace std; //找到循环链表的入口节点 ListNode* meetingNode(ListNode* pHead) { if(pHead == NULL) return NULL; ListNode* pSlow = pHead ->m_pNext; if(pSlow == NULL) return NULL; ListNode* pFast = pSlow ->m_pNext; while (pFast != NULL && pSlow != NULL) { if (pFast == pSlow) return pFast; pSlow = pSlow ->m_pNext; pFast = pFast ->m_pNext; if(pFast != NULL) pFast = pFast ->m_pNext; } return NULL; } ListNode* EntryNodeOfLoop(ListNode* pHead) { ListNode* meetNode = meetingNode(pHead); if(meetNode == NULL) return NULL; int loopNum = 1; ListNode* pNode1 = meetNode; while (pNode1 ->m_pNext != meetNode) { pNode1 = pNode1 ->m_pNext; loopNum ++; } pNode1 = pHead; for (int i=0; i<loopNum; i++) pNode1 = pNode1 ->m_pNext; ListNode* pNode2 = pHead; while (pNode2 != pNode1) { pNode1 = pNode1 ->m_pNext; pNode2 = pNode2 ->m_pNext; } return pNode1; }
<pre name="code" class="cpp">// ==================== Test Code ==================== void Test(char* testName, ListNode* pHead, ListNode* entryNode) { if(testName != NULL) printf("%s begins: ", testName); if(EntryNodeOfLoop(pHead) == entryNode) printf("Passed.\n"); else printf("FAILED.\n"); } // A list has a node, without a loop void Test1() { ListNode* pNode1 = CreateListNode(1); Test("Test1", pNode1, NULL); DestroyList(pNode1); } // A list has a node, with a loop void Test2() { ListNode* pNode1 = CreateListNode(1); ConnectListNodes(pNode1, pNode1); Test("Test2", pNode1, pNode1); delete pNode1; pNode1 = NULL; } // A list has multiple nodes, with a loop void Test3() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(2); ListNode* pNode3 = CreateListNode(3); ListNode* pNode4 = CreateListNode(4); ListNode* pNode5 = CreateListNode(5); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode3); Test("Test3", pNode1, pNode3); delete pNode1; pNode1 = NULL; delete pNode2; pNode2 = NULL; delete pNode3; pNode3 = NULL; delete pNode4; pNode4 = NULL; delete pNode5; pNode5 = NULL; } // A list has multiple nodes, with a loop void Test4() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(2); ListNode* pNode3 = CreateListNode(3); ListNode* pNode4 = CreateListNode(4); ListNode* pNode5 = CreateListNode(5); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode1); Test("Test4", pNode1, pNode1); delete pNode1; pNode1 = NULL; delete pNode2; pNode2 = NULL; delete pNode3; pNode3 = NULL; delete pNode4; pNode4 = NULL; delete pNode5; pNode5 = NULL; } // A list has multiple nodes, with a loop void Test5() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(2); ListNode* pNode3 = CreateListNode(3); ListNode* pNode4 = CreateListNode(4); ListNode* pNode5 = CreateListNode(5); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode5); Test("Test5", pNode1, pNode5); delete pNode1; pNode1 = NULL; delete pNode2; pNode2 = NULL; delete pNode3; pNode3 = NULL; delete pNode4; pNode4 = NULL; delete pNode5; pNode5 = NULL; } // A list has multiple nodes, without a loop void Test6() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(2); ListNode* pNode3 = CreateListNode(3); ListNode* pNode4 = CreateListNode(4); ListNode* pNode5 = CreateListNode(5); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); Test("Test6", pNode1, NULL); DestroyList(pNode1); } // Empty list void Test7() { Test("Test7", NULL, NULL); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); return 0; }
相关文章推荐
- Javascript 私有变量
- mysql分表和表分区详解
- 面试需要注意的十二个得分细节
- mysql外键理解
- BootStrap入门
- JUnit使用参数测试和一组测试
- memcache启动多个服务
- PHP关于按位取反结果的推导过程
- tcpdump
- Servlet
- 多线程五 经典线程同步之事件Event
- 设计模式面试大集锦
- 最小生成树之Kruskal(克鲁斯卡尔)算法
- js设计模式
- PHP_OS判断操作系统
- shell获取db信息及上传下载操作
- Android开发中Handler的经典总结
- Oracle FORM Bulider 校验多行多列数据重复的一种方法
- socket穿透代理代码(C++版)
- iOS 循环线程的实现