码迷,mamicode.com
首页 > 其他好文 > 详细

56 - 链表中环的入口节点

时间:2015-08-01 22:05:56      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:链表

题目:
一个链表中包含环,如何找出环的入口节点? 例如 1->2->3->4->5->6->(3) ; 的链表中,环的入口及诶到哪是节点 3。


解析:

  • 首先找到链表中的环:定义2个指针,一个快指针一次走2步,一个慢指针一次走1步,如果2个指针能够相遇,证明有环。
  • 统计链表中环的长度:从相遇指针开始,固定 1 个指针,另一个指针从相遇指针走,当2个指针再次相遇时,即走了 1 圈,得到环的长度 len。
  • 2个指针指向链表开头,1个指针先走 len 步,另一个指针从头和前一个指针一起走,当 2 个指针相遇时,即是环的入口。
#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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

56 - 链表中环的入口节点

标签:链表

原文地址:http://blog.csdn.net/quzhongxin/article/details/47190537

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!