标签:链表
题目:
一个链表中包含环,如何找出环的入口节点? 例如 1->2->3->4->5->6->(3) ; 的链表中,环的入口及诶到哪是节点 3。
解析:
#include <iostream>
using namespace std;
class Node {
public:
int val;
Node* next;
Node(int v, Node* n = NULL):val(v), next(n) {};
};
int GetCircleNodeNums(Node* pHead) {
if (pHead == NULL)
return 0;
// 一快一慢,相遇时,则找到环
Node* pSlow = pHead;
Node* pFast = pSlow->next;
while (pFast != NULL && pSlow != NULL) {
if (pFast == pSlow)
break;
pSlow = pSlow->next;
if (pFast->next) {
pFast = pFast->next->next;
} else {
break;
}
}
// 固定一个指针,一个指针走,再次相遇时,则是一圈,得到环长度
int counts = 0; // 如果 p1, p2 有一个为NULL,则不存在环,返回0
Node* p1 = pFast, *p2 = pSlow;
if (p1 == p2 && p1 != NULL) {
p1 = p1->next;
counts++;
while (p1 != p2) {
p1 = p1->next;
counts++;
}
}
return counts;
}
Node* FindCircleEntrance(Node* pHead) {
if (pHead == NULL)
return NULL;
int circle_len = GetCircleNodeNums(pHead);
if (circle_len == 0)
return NULL; // 没有环
Node* p1 = pHead, *p2 = pHead;
// p1 先走一个环的长度
while (circle_len) {
p1 = p1->next;
circle_len--;
}
// p1, p2 一起走,相遇时则是环的入口
while (p1 != p2) {
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
int main() {
// 1->2->3->4->5->6->(3)
Node* pList = NULL;
Node* pNode1 = new Node(1, NULL);
Node* pNode2 = new Node(2, NULL);
Node* pNode3 = new Node(3, NULL);
Node* pNode4 = new Node(4, NULL);
Node* pNode5 = new Node(5, NULL);
Node* pNode6 = new Node(6, NULL);
pNode1->next = pNode2;
pNode2->next = pNode3;
pNode3->next = pNode4;
pNode4->next = pNode5;
pNode5->next = pNode6;
pNode6->next = pNode3;
pList = pNode1;
cout << "环的长度 :"<< GetCircleNodeNums(pList) << endl;
Node* EntranceNode = FindCircleEntrance(pList);
if (EntranceNode)
cout << "环的入口节点的值:"<< EntranceNode->val << endl;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:链表
原文地址:http://blog.csdn.net/quzhongxin/article/details/47190537