约瑟夫环
是一个数学的应用问题:
已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
这个就是约瑟夫环问题的实际场景,有一种是要通过输入n,m,k三个正整数,来求出列的序列。这个问题采用的是典型的循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素。
那么如何用单链表实现约瑟夫环呢?
第一步建立一个具有n个链结点,无头结点的循环链表(假设每次都从头结点开始报数):
第二步,开始报数
第三步,报到m的人出局,删除节点(删除节点之后要注意使用free函数,释放该空间)。
第四步,当循环结束的时候,一定记得要解环,令最后一个节点的下一个指针域指向空。
最后,程序如下所示:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<Windows.h>
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
typedef int DataType;
typedef struct Node
{
DataType _data;
struct Node * _pNext;
}*pNode;
//初始化单链表
void InitList(pNode* pHead)
{
assert(pHead);
*pHead = NULL;
}
//创建一个新节点
pNode BuyNode(DataType data)
{
pNode pNewNode = (pNode)malloc(sizeof(struct Node));
if(NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
//头插
void PushBack(pNode* pHead,DataType _data)
{
assert(pHead);
if(NULL == *pHead)
{
*pHead = BuyNode(_data);
}
else
{
pNode pTailNode = *pHead;
while(pTailNode->_pNext)
{
pTailNode = pTailNode->_pNext;
}
pTailNode->_pNext = BuyNode(_data);
}
}
//顺序打印单链表
void PrintList(pNode pHead)
{
pNode pCur = pHead;
while(pCur)
{
printf("%d--->",pCur->_data);
pCur = pCur->_pNext;
}
printf("NULL\n");
}
// 单链表实现约瑟夫环
pNode JosephCircle(pNode pHead, int M)
{
pNode pCur;
pNode pDel;
int count = 0;
if(NULL == pHead)
return NULL;
pCur = pHead;
//构环
while(pCur->_pNext)
{
pCur=pCur->_pNext;
}
pCur->_pNext = pHead;
pCur = pHead;
while(pCur != pCur->_pNext)
{
//报数
count = M;
while(--count)
{
pCur = pCur->_pNext;
}
//删节点
pDel = pCur->_pNext;
pCur->_data = pDel->_data;
pCur->_pNext = pDel->_pNext;
free(pDel);
}
//解环
pCur->_pNext = NULL;
return pCur;
}
//测试
void test()
{
pNode pHead;
pNode pJosephNode = NULL;//最后存活的节点
DataType m;//出局密码
InitList(&pHead);
PushBack(&pHead,1);
PushBack(&pHead,2);
PushBack(&pHead,3);
PushBack(&pHead,4);
PushBack(&pHead,5);
PushBack(&pHead,6);
printf("请输入出局密码:>");
scanf("%d",&m);
printf("原链表为:>");
PrintList(pHead);
pJosephNode = JosephCircle(pHead,m);
printf("最后存活的为:>");
PrintList(pJosephNode);
}
int main(){
test();
system("pause");
return 0;
}
程序运行结果如下所示: