【C/C++练习题】找出链表中环的入口节点

举报
王建峰 发表于 2021/11/19 01:12:52 2021/11/19
【摘要】 《剑指Offer》面试题23:链表中环的入口结点 1 题目 一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中,环的入口结点是结点3。     2 算法思路 找出环中的某一个节点:分别设置指针pSlow pFast在环中遍历元素,pFast的速度快,两个指针最终会在环中的某位置相遇计算...

《剑指Offer》面试题23:链表中环的入口结点


1 题目

一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中,环的入口结点是结点3。

 

 

2 算法思路

  1. 找出环中的某一个节点:分别设置指针pSlow pFast在环中遍历元素,pFast的速度快,两个指针最终会在环中的某位置相遇
  2. 计算环中节点的个数:从节点出发,一边遍历节点边统计个数,当再次回到起点的时候,得总节点个数k
  3. 找出入口节点:设置pFast为pSlow右边第k个指针,同时移动两指针。直到相遇,得入口节点

 

3 代码


  
  1. #include "iostream"
  2. #include "cstdlib"
  3. using namespace std;
  4. //问题:找出链表中环的入口节点
  5. typedef struct node
  6. {
  7. int m_nValue;
  8. node* m_pNext;
  9. }ListNode;
  10. ListNode* Meeting_node(ListNode* pHead);
  11. ListNode* Enter_node(ListNode* pHead);
  12. void test01()
  13. {
  14. ListNode* pHead = NULL;
  15. ListNode* pNode1 = NULL;
  16. ListNode* pNode2 = NULL;
  17. ListNode* pNode3 = NULL;
  18. ListNode* pThis = NULL;
  19. pHead = (ListNode*)malloc(sizeof(ListNode));
  20. pNode1 = (ListNode*)malloc(sizeof(ListNode));
  21. pNode2 = (ListNode*)malloc(sizeof(ListNode));
  22. pNode3 = (ListNode*)malloc(sizeof(ListNode));
  23. pThis = (ListNode*)malloc(sizeof(ListNode));
  24. if (pHead == NULL || pNode1 == NULL || pNode2 == NULL || pNode3 == NULL || pThis == NULL)
  25. {
  26. cout << "malloc fail" << endl;
  27. return ;
  28. }
  29. pHead->m_nValue = 0;
  30. pHead->m_pNext = pNode1;
  31. pNode1->m_nValue = 1;
  32. pNode1->m_pNext = pNode2;
  33. pNode2->m_nValue = 2;
  34. pNode2->m_pNext = pNode3;
  35. pNode3->m_nValue = 3;
  36. pNode3->m_pNext = pNode1; //构成一个环 0 -> 1 -> 2 -> 3 -> (1) -> ....
  37. pThis = Enter_node(pHead);
  38. cout << "enter node:" << pThis->m_nValue << endl;
  39. }
  40. int main(int argc, char const *argv[])
  41. {
  42. test01();
  43. return 0;
  44. }
  45. //功能:取环中任一节点
  46. //输入:pHead 链表头节点指针
  47. //返回:目标节点指针
  48. ListNode* Meeting_node(ListNode* pHead)
  49. {
  50. //1.检查输入参数的合法性
  51. if (NULL == pHead)
  52. {
  53. return NULL;
  54. }
  55. ListNode* pSlow = pHead;
  56. ListNode* pFast = pHead->m_pNext;
  57. //2.找出环内某节点
  58. while ((pSlow->m_pNext != NULL) && (pFast->m_pNext != NULL))
  59. {
  60. if (pSlow == pFast)
  61. {
  62. return pFast;
  63. }
  64. pSlow = pSlow->m_pNext; //偏移1
  65. pFast = pFast->m_pNext; //偏移2
  66. if (pFast->m_pNext != NULL)
  67. {
  68. pFast = pFast->m_pNext;
  69. }
  70. }
  71. //3.没有环结构
  72. return NULL;
  73. }
  74. //功能:取环的入口节点
  75. //输入:pHead 链表头节点指针
  76. //返回:目标节点指针
  77. ListNode* Enter_node(ListNode* pHead)
  78. {
  79. //1.检查输入参数的合法性
  80. if (NULL == pHead)
  81. {
  82. return NULL;
  83. }
  84. ListNode* pNode1 = Meeting_node(pHead);
  85. ListNode* pNode2 = pNode1->m_pNext;
  86. int count = 1;
  87. //2.统计环的节点个数count
  88. while (pNode1 != pNode2)
  89. {
  90. ++count;
  91. pNode2 = pNode2->m_pNext;
  92. }
  93. //3.找出入口节点
  94. pNode1 = pHead;
  95. pNode2 = pHead;
  96. for (int i = 0;i < count;i++)
  97. {//调整pNode1 pNode2的相对位置
  98. pNode2 = pNode2->m_pNext;
  99. }
  100. while (pNode1 != pNode2)
  101. {
  102. pNode1 = pNode1->m_pNext;
  103. pNode2 = pNode2->m_pNext;
  104. }
  105. //4.返回环入口指针
  106. return pNode1;
  107. }

 

4 运行结果

文章来源: blog.csdn.net,作者:hinzer,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/feit2417/article/details/98722797

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。