约瑟夫环
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。它也是算法设计中一个老生常谈的问题,有循环链表法、数组法、数学分析法等。
链表法:充分利用循环链表的循环特性,也是最容易想到、最容易实现的一种,前提是对链表要有充分的了解,对指针操作不感冒;
数学分析法:不考虑算法问题,将约瑟夫环抽象为一个单纯的数学问题,通过数学推理,可得到一个简单的数学公式,x'=(x+k)%n,这种方法算法设计极简单,但对数学推导功底要求较高;
数组法:为常规一般的编程方法,通过数组元素的增减处理,借助合理的逻辑设计达到的设计算法。符合常规算法设计思维,但对逻辑思维要求较高。
考虑到网上、书籍中多以链表法居多,我们就用数组法实现:
算法:
#include<stdio.h>
int main()
{
int i,j,k,a[10000],total,startIndex,cycleNumber,aimIndex,temp;
printf("-------------------------\n");
printf("请输入总人数:\n");
scanf("%d",&total);
printf("请输入起始编号:\n");
scanf("%d",&startIndex);
printf("请输入循环个数:\n");
scanf("%d",&cycleNumber);
for(i=0;i<total;i++)
{
a[i]=i+1;
}
aimIndex=startIndex-2;
while(total-1)
{
for(i=0;i<cycleNumber;i++)
{
if(aimIndex<total-1)
{
aimIndex++;
}
else
{
aimIndex=0;
}
}
for(i=aimIndex;i<total;i++)
{
temp=a[i+1];
a[i]=temp;
}
for(i=0;i<total-1;i++)
{
printf("%d ",a[i]);
}
printf("###\n");
aimIndex-=1;
total--;
}
printf("The last number is :%d\n",a[0]);
printf("-------------------------\n");
return 0;
}