單鏈表實現約瑟夫環

何謂約瑟夫環?
約瑟夫環是一個數學的應用問題:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號爲k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列,剩下最後一個人。

舉個例子:

按照以上規則,從0開始數,最後剩下的是數字5。


函數定義:
Node*JosephCycle(PNode*ppHead, int k,int m);//其中k爲起始位置,m爲要刪除的位置

代碼如下:
頭文件SList.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct SListNode
{
	DataType data;
	 struct SListNode*pNext;
}Node, *PNode;
PNode* BuyNode(DataType data);//創建節點
void DestroyNode(PNode** ppHead);//銷燬節點
void IntiSList(PNode*pHead);//初始化
Node* PushBackSList(PNode* ppHead, DataType data);// 尾插
Node*JosephCycle(PNode*ppHead, int k,int m);//實現約瑟夫環
SList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include"SList.h"

PNode* BuyNode(DataType data)
{
	Node*pNewNode = (Node*)malloc(sizeof(Node));
	if (pNewNode != NULL)
	{
		pNewNode->data = data;
		pNewNode->pNext = NULL;
	}
	return pNewNode;
}
void DestroyNode(PNode* ppHead)
{
	if (ppHead == NULL)
		return;
	if (*ppHead == NULL)
		return;
	free(*ppHead);
}
void IntiSList(PNode*pHead)
{
	assert(pHead);
	*pHead = NULL;
}
Node* PushBackSList(PNode* ppHead, DataType data)
{
	assert(ppHead);
	Node*pTailNode = *ppHead;
	if (*ppHead == NULL)
	{
		*ppHead=BuyNode(data);
		return *ppHead;
	}
	else
	{
		while (pTailNode->pNext)
		{
			pTailNode = pTailNode->pNext;
		}
		pTailNode->pNext = (BuyNode(data));
	}
	return pTailNode->pNext;
}
Node*JosephCycle(PNode*ppHead,int k,int m)
{
 assert(ppHead);
 Node*pDel = NULL;
 Node*pCur = *ppHead;
 while (k--)//從第k個元素開始
 {
  pCur = pCur->pNext;
 }
 int i = m;
 while (1)
 {
  if (pCur == pCur->pNext)//只剩一個元素
  {
   pCur->pNext = NULL;
   printf("%c\n", pCur->data);
   break;
  }
  while (m>1)//數到m個元素刪除
  {
   pCur = pCur->pNext;//此時的pCur爲刪除的前一個節點
   m--;
  }
  m = i;//恢復m以便下一次循環
  pDel = pCur->pNext;//標記刪除節點
  pCur->pNext = pDel->pNext;//將刪除節點前一個的pNext指向刪除節點的後一個
  pCur = pCur->pNext;//將pCur後移一位重新開始
  DestroyNode(&pDel);
 }
 return pCur;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<Windows.h>
#include"SList.h"
void test()
{
 Node* pNode;
 IntiSList(&pNode);
 Node*pos_a=PushBackSList(&pNode, 'a');
 PushBackSList(&pNode, 'b');
 PushBackSList(&pNode, 'c');
 PushBackSList(&pNode, 'd');
 PushBackSList(&pNode, 'e');
 Node*pos_f=PushBackSList(&pNode, 'f');
 pos_f->pNext = pos_a;//將點f指向a
 JosephCycle(&pNode, 0, 3);
}
int main()
{
 test();
 system("pause");
 return 0;
}

以上大概就是如何實現約瑟夫環。


























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章