// 面试题23:链表中环的入口结点
// 题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中,
// 环的入口结点是结点3。 #include <iostream>
#include "List.h" ListNode* MeetingNode(ListNode* pHead)//鲁棒一:先确定有没有环,有的话先求得环中任意一个节点
{
if (pHead == nullptr)//若头结点为空
return nullptr; ListNode* pSlow = pHead->m_pNext;
if (pSlow == nullptr)//若只有一个节点
return nullptr; ListNode* pFast = pSlow->m_pNext;
while (pFast != nullptr && pSlow != nullptr)//判断碰到尾节点后有没有环
{
if (pFast == pSlow)
return pFast; pSlow = pSlow->m_pNext; pFast = pFast->m_pNext;
if (pFast != nullptr)//判断碰到尾节点后有没有环
pFast = pFast->m_pNext;
} return nullptr;
} ListNode* EntryNodeOfLoop(ListNode* pHead)//开始计算入口节点,第一步先求环的个数,第二步通过两个前后指针计算入口节点
{
ListNode* meetingNode = MeetingNode(pHead);
if (meetingNode == nullptr)//如果存在环,得到一个环中节点
return nullptr; // 得到环中结点的数目
int nodesInLoop = ;
ListNode* pNode1 = meetingNode;
while (pNode1->m_pNext != meetingNode)
{
pNode1 = pNode1->m_pNext;
++nodesInLoop;
} // 先移动pNode1,次数为环中结点的数目
pNode1 = pHead;
for (int i = ; i < nodesInLoop; ++i)
pNode1 = pNode1->m_pNext; // 再移动pNode1和pNode2
ListNode* pNode2 = pHead;
while (pNode1 != pNode2)//二者只能相遇在入口处
{
pNode1 = pNode1->m_pNext;
pNode2 = pNode2->m_pNext;
} return pNode1;
} // ==================== Test Code ====================
void Test(const char* testName, ListNode* pHead, ListNode* entryNode)
{
if (testName != nullptr)
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(); Test("Test1", pNode1, nullptr); DestroyList(pNode1);
} // A list has a node, with a loop
void Test2()
{
ListNode* pNode1 = CreateListNode();
ConnectListNodes(pNode1, pNode1); Test("Test2", pNode1, pNode1); delete pNode1;
pNode1 = nullptr;
} // A list has multiple nodes, with a loop
void Test3()
{
ListNode* pNode1 = CreateListNode();
ListNode* pNode2 = CreateListNode();
ListNode* pNode3 = CreateListNode();
ListNode* pNode4 = CreateListNode();
ListNode* pNode5 = CreateListNode(); ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode3); Test("Test3", pNode1, pNode3); delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
} // A list has multiple nodes, with a loop
void Test4()
{
ListNode* pNode1 = CreateListNode();
ListNode* pNode2 = CreateListNode();
ListNode* pNode3 = CreateListNode();
ListNode* pNode4 = CreateListNode();
ListNode* pNode5 = CreateListNode(); ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode1); Test("Test4", pNode1, pNode1); delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
} // A list has multiple nodes, with a loop
void Test5()
{
ListNode* pNode1 = CreateListNode();
ListNode* pNode2 = CreateListNode();
ListNode* pNode3 = CreateListNode();
ListNode* pNode4 = CreateListNode();
ListNode* pNode5 = CreateListNode(); ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode5); Test("Test5", pNode1, pNode5); delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
} // A list has multiple nodes, without a loop
void Test6()
{
ListNode* pNode1 = CreateListNode();
ListNode* pNode2 = CreateListNode();
ListNode* pNode3 = CreateListNode();
ListNode* pNode4 = CreateListNode();
ListNode* pNode5 = CreateListNode(); ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5); Test("Test6", pNode1, nullptr); DestroyList(pNode1);
} // Empty list
void Test7()
{
Test("Test7", nullptr, nullptr);
} int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
system("pause");
return ;
}

最新文章

  1. String空值判定
  2. JavaWeb:实现文件上传
  3. Saltstack数据系统Grains和Pillar(三)
  4. NAS服务器局域网内IPad、手机、电视盒子等联网播放
  5. ASP.NET WebAPI 09 Controller的激活
  6. centos 6.5 64位编译 apache2.4
  7. [Android]天气App 1
  8. 使用phantomjs实现highcharts等报表通过邮件发送
  9. VS2010使用附加进程的方式调试IIS中的页面介绍
  10. JSP基础学习(二)
  11. memset函数的使用
  12. 移动WEB模拟原声APP滑动删除
  13. 【Axios】前端页面使用axios调用后台接口
  14. 论文阅读笔记:【Transforming Auto-encoders】
  15. spring boot 日志介绍 以及 logback配置示例
  16. mysql表空间文件
  17. 批量打回未报bug修复
  18. CodeForces - 600C Make Palindrome 贪心
  19. 【Linux】通过SSH修改调整Linux时间和时区
  20. 专业软件 —— Adobe Audition

热门文章

  1. WPF学习笔记-用Expression Design制作矢量图然后导出为XAML
  2. java文件生成
  3. Multinoulli distribution
  4. eclipse工具maven项目打包文件不是最新修改的
  5. 关于QStandardItemModel
  6. JMeter:全面的乱码解决方案
  7. Google&#39;s Machine Learning Crash Course #01# Introducing ML &amp; Framing &amp; Fundamental terminology
  8. PHP二维数组排序(感谢滔哥lvtao.net)
  9. 05: 配置yum源
  10. 基于qml创建最简单的图像处理程序(1)-基于qml创建界面