继上篇博客之------------
什么是约瑟夫环
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。选定一个人作为开始,报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
约瑟夫环
SListNode* JosephCircle(SListNode* pHead, DataType m)//约瑟夫环
{
//1.报数
//2.删除结点
SListNode* pCur = pHead;
SListNode* pDel = NULL;
while (pCur->next != pCur)
{
int M = m;
while (--M)
{
pCur = pCur->next;
pDel = pCur->next;
pCur->data = pDel->data;
pCur->next = pDel->next;
free(pDel);
}
}
}
判断是否成环
SListNode* HasListCircle(SListNode* pHead)//判断是否带环
{
SListNode* pFast = pHead;
SListNode* pSlow = pHead;
while (pFast && pFast->next)
{
pFast = pFast->next->next;//只能让快的一次走两步,如果三步或以上,
pSlow = pSlow->next; //可能刚好是一个环的长度,两个就永远相遇不了。
if (pFast == pSlow)//两个指针在环里肯定会相遇,所以任意返回一个
return pFast;
}
return NULL; //没有环,返回空
}
求环的长度
int GetCircleLen(SListNode* pMeetNode)//求环的长度
{
int count = 0;
SListNode* pCur = pMeetNode;
if (pMeetNode == NULL)
return 0;
while (pCur->next != pMeetNode)
{
count++;
pCur = pCur->next;
}
return count;
}
环的入口点
SListNode* GetEnterNode(SListNode* pHead, SListNode* pMeetNode)//环的入口点
{
SListNode* pH = pHead;
SListNode* pM = pMeetNode;
if (pHead == NULL || pMeetNode == NULL)
return NULL;
while (pH != pM)
{
pH = pH->next;
pM = pM->next;
}
return pM;//如果相遇点和头指针后来相遇了,则相遇点是入口
}