判断链表是否有环以及求环中第一个结点

题目:给定单链表,如果有环的话请返回从头结点进入环的第一个结点。

答:

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <ctime>

using namespace std;

struct ListNode
{
    int m_nKey;
    ListNode* m_pNext;
};

//构造链表
void CreateList(ListNode *&pHead, ListNode *&pFirstNode)
{
    fstream fin("list.txt");
    ListNode *pNode = NULL;
    ListNode *pTmp = NULL;
    int data;
    fin>>data;
    srand((unsigned)time(NULL));
    while (data)
    {
        pNode = new ListNode;
        pNode->m_nKey = data;
        pNode->m_pNext = NULL;
        if (NULL == pHead)
        {
            pHead = pNode;
            pTmp = pNode;
        }
        else
        {
            pTmp->m_pNext = pNode;
            pTmp = pNode;
        }

        if (NULL == pFirstNode && !(rand() % 5))
        {
            pFirstNode = pNode;
        }

        fin>>data;
    }
    pNode->m_pNext = pFirstNode;
}


//判断链表是否有环
bool IsCircle(ListNode *pHead)
{
    if (NULL == pHead)
    {
        return false;
    }
    ListNode *pFast = pHead;
    ListNode *pSlow = pHead;
    while (pFast && NULL != pFast->m_pNext)
    {

        pFast = pFast->m_pNext->m_pNext;
        pSlow = pSlow->m_pNext;
        if (pFast == pSlow)
        {
            break;
        }
    }
    return !(pFast == NULL || pFast->m_pNext == NULL);
}

//判断链表是否有环以及求环中第一个结点
ListNode* FindFirstCommonNode(ListNode *pHead)
{
    if (NULL == pHead)
    {
        return NULL;
    }
    ListNode *pFast = pHead;
    ListNode *pSlow = pHead;
    while (pFast && NULL != pFast->m_pNext)
    {

        pFast = pFast->m_pNext->m_pNext;
        pSlow = pSlow->m_pNext;
        if (pFast == pSlow)
        {
            break;
        }
    }
    if((pFast == NULL || pFast->m_pNext == NULL))
    {
        return NULL;
    }
    pSlow = pHead;
    while (pSlow != pFast)
    {
        pSlow = pSlow->m_pNext;
        pFast = pFast->m_pNext;
    }
    return pSlow;
}

int _tmain(int argc, _TCHAR* argv[])
{
    ListNode *pHead = NULL;
    ListNode *pFirstNode = NULL;
    CreateList(pHead, pFirstNode);
    ListNode* pNode = NULL;
    if (NULL != (pNode = FindFirstCommonNode(pHead)))
    {
        cout<<"有环,第一个相交结点为: "<<pNode->m_nKey<<endl;
    }
    else
    {
        cout<<"无环"<<endl;
    }

    cout<<endl;
    return 0;
}

运行界面如下:

建造链表的list.txt文件如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0
原文地址:https://www.cnblogs.com/venow/p/2662007.html