数据结构——不采用链表,实现约瑟夫环问题
问题描述
有n个小朋友坐在一起玩游戏,编号为1,2,…,n,按照编号顺序围成一圈,他们按照顺序依次从1开始报数,报到m或者m的倍数时出列,他的下一个人继续报数,照这样重复下去,直到只剩下一个小朋友。请编写一各程序,输入n和m,按照顺序输出编号或者找出最后一个剩下的小朋友。
问题分析
- 传统做法是利用循环链表来完成,但是如标题所见,采用数组来实现。
- 利用数组的话,不需要再利用数据结构来实现链表,而是直接利用逻辑,依次踢出被淘汰的小朋友,这样直到数组中只剩下唯一一个同学时,算法结束。
问题实现
- 输入人数n和报数m。
- 定义一个数组,来存储编号。
- 当人数大于1时,进入循环,依次报数。循环中当报数满足题目淘汰规则时,将该人踢出。
- 循环结束,输出数组中唯一存在的一个编号。
代码展示
#include<iostream>
using namespace std; //代码中展示m为7,这个可以自行输入定义
int main(){
int n;
cout << "please input the number of student: " << endl;
cin >> n;
int a[100];
for(int i = 0; i < n; i++) // 将数组中依次按顺序填入编号
{
a[i] = i + 1;
}
int num = n, count = 1, i = 0;//num表示剩余人数,count表示当前报数,i表示现在报数的人在数组中在第i个位置。
while( num > 1 ){ //人数大于1保持循环
if(count%7 == 0){ //遇到踢出的人时,将后面的数依次向前移动一个位置,相当于把当前报数的人踢出。
for(int j = i + 1; j < num; j++)
{
a[j-1] = a[j];
}
count++;
num--;
i=i % num;
}
i=( i + 1 ) % num;
count++;
}
cout << "the last one is: " << a[0] << endl;
return 0;
}
结果展示
- 当8个人时,输出为4,即编号为4的同学是赢家。
- 当2个人时,输出为2,即单数1必输。
问题总结
我是用c++语言写的,稍加改动即可完善成其他语言。谢谢支持!