何谓约瑟夫环?
约瑟夫环是一个
数学的应用
问题:已知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;
}
以上大概就是如何实现约瑟夫环。