何謂約瑟夫環?
約瑟夫環是一個數學的應用問題:已知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;
}
以上大概就是如何實現約瑟夫環。