1. 程式人生 > >連結串列面試題----約瑟夫環相關

連結串列面試題----約瑟夫環相關

約瑟夫環相關連結串列面試題

繼上篇部落格之------------

什麼是約瑟夫環

約瑟夫環(約瑟夫問題)是一個數學的應用問題:已知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;//如果相遇點和頭指標後來相遇了,則相遇點是入口
}