链表带环的情况下就需要活用指针:
- 两个指针的组合可以很好的遍历结点
- 两个指针的行走速度有差异即可进行环的相关判断(一步、两步、先走后走)
- 链表每走一步都要注意下一个节点为nullptr时,是否会影响到程序的鲁棒性,造成程序的崩溃,走两步的指针更需要注意这个问题,需要判断两次!(否则为nullptr也就不会再走下去)
#include <iostream> #include <string> #include <vector> #include <stack> using namespace std; typedef int datatype; struct Node { datatype value; Node* Next_Node; }; struct Node_circle { unsigned int Number; Node *entrace; }; //判断链表中是否有环 Node* Exist_circle(Node *first) { if (first == nullptr || first->Next_Node == nullptr) { return nullptr; } Node* Node_temp1 = first->Next_Node; Node* Node_temp2 = Node_temp1->Next_Node; while (Node_temp2 != nullptr && Node_temp1 != nullptr) { Node_temp1 = Node_temp1->Next_Node; Node_temp2 = Node_temp2->Next_Node; //在链表中,每一个节点为nullptr时是否影响到程序的鲁棒性,造成程序崩溃,都必须考虑在内 if (Node_temp2->Next_Node != nullptr) { Node_temp2 = Node_temp2->Next_Node; } if (Node_temp1 == Node_temp2) { return Node_temp1; break; } } return nullptr; } //输出环中结点的个数以及环的入口 Node_circle* Find_circle(Node *first) { Node* Node_temp5 = Exist_circle(first); if (Node_temp5 == nullptr) { return nullptr; } int number = 1; //已存在环,无需判断下一个节点是否为nullptr了 Node* Node_temp3 = Node_temp5->Next_Node; while (Node_temp3 != Node_temp5) { Node_temp3 = Node_temp3->Next_Node; number++; } Node* entrace = first; for (int i = 0;i<number;i++) { entrace = entrace->Next_Node; } Node* Node_temp4 = first; while (Node_temp4 != entrace) { Node_temp4 = Node_temp4->Next_Node; entrace = entrace->Next_Node; } Node_circle* circle_Node; circle_Node->Number = number; circle_Node->entrace = entrace; return circle_Node; } void main() { system("pause"); }