链表是否构成环、环的长度以及环的入口点的求法

来源:互联网 发布:简述什么是波士顿矩阵 编辑:程序博客网 时间:2024/06/10 14:44

链表是否构成环、环的长度以及环的入口点的求法

题目:判断一个链表是否构成环,并求出所构成环的长度,以及环的入口点。
基本思想:
(1)判断是否构成环的方法
定义快慢两个指针p1和p2,让这两个指针指向链表的头结点。假设该链表中有n个结点,让快指针比慢指针快两步,之后两个指针沿着链表向前走,若可以构成环,快指针总会比慢指针多走k圈,直到相遇;若不能构成环,则快指针和慢指针永远不可能相遇。
(2)求环的长度
若没有构成环,返回0,此时的该链表已经构成环。求环的长度。
(3)求环的入口点
同样,快指针走两步时慢指针走一步,于是有以下的推导。
假设,快指针走了m圈,慢指针走了n圈。分析如下图所示。


代码实现:
#include #include using namespace std;typedef int DataType;struct ListNode{DataType _data;ListNode* _next;ListNode(const DataType x):_data(x), _next(NULL){}};class List{typedef ListNode Node;public:List():_root(NULL){}void Push(DataType x){if (_root == NULL){_root = new Node(x);}else{Node* tmp = _root;while (tmp->_next){tmp = tmp->_next;}tmp->_next = new Node(x);}}Node* Find(DataType x){Node* cur = _root;while (cur){if (cur->_data == x){return cur;}cur = cur->_next;}return NULL;}Node* JudgeCircle()                          //判断是否带环{Node* slow = _root;                      //定义一个快指针和慢指针,快指针走两步,慢指针走一步Node* fast = _root;while (fast&&fast->_next){fast = fast->_next->_next;slow = slow->_next;if (fast == slow){return fast;}}return NULL;}int GetCircleLength(Node* meet)               //求环的长度{Node* tmp = JudgeCircle();if (tmp == NULL){return 0;}Node* cur = meet;int count = 1;while (cur->_next !=meet){cur = cur->_next;count++;}return count;}Node* GetEntryNode(Node*  meetNode)               //求环的入口点{Node* fast = _root;Node* slow = meetNode;while (fast != slow){fast = fast->_next;slow = slow->_next;}return fast;}void Printf(){Node* cur = _root;while (cur){cout << cur->_data << "->";cur = cur->_next;}cout << "NULL" << endl;}protected:Node* _root;};void Test(){List s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);s1.Push(5);s1.Push(6);s1.Push(7);s1.Printf();ListNode* ret = NULL;ret = s1.Find(7);/*if (ret != NULL){cout << "找到了" << endl;}else{cout << "没找到" << endl;}*/ret->_next =s1.Find(5);ListNode* s = s1.JudgeCircle();if (s != NULL){cout << "可以构成环" << endl;}else{cout << "不能构成环" << endl;}cout <<"环的长度为:"<_data << endl;}
运行结果:

阅读全文
0 0
原创粉丝点击