判断链表是否有环以及求环中第一个结点
题目:给定单链表,如果有环的话请返回从头结点进入环的第一个结点。
答:
#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