其实,今天写这个关于c语言数组实现约瑟夫循环是因为前两天我们《数据结构》上机课的一道练习题就是这个。但是呢,练习题上的要求是用单链表实现(这就尴尬了 )。 上课我是能听得懂的,但是估计是由于平时很少亲自动手写链表,结果这次上机,我感觉我就和个憨批样的,一脸蒙蔽(*留下了无知的眼泪 * ) 。后来呢,也就试着用别的方法解决一下。最后想起了c语言(我貌似也就只会这个qwq )。 (等我哪天学会了我在用链表写一次再发一篇)。
#include <stdio.h> #include<windows.h> #define N 100 int main() { int n, m, s; printf("n表示总的玩家数\n"); printf("m表示报该数出列\n"); printf("s表示从第几个人开始报数\n"); printf("请分别输入nms的值\n"); scanf_s("%d%d%d", &n, &m, &s); //第一行表示总的旅客数,输入的第二行表示报数值,输入的第三行表示报数人的起始编号。 int a[N] = { 0 };//数组初始化 int i, j; for (i = 0; i < n; i++)//数组遍历 { a[i] = i + 1;//a[0]=1,..... } i = s - 1;//数组起点,因为数组下标=人物编号-1 。 int x = 0; while (n > 1)//最后一个人是游戏结束。 { i = (i + m - 1) % n; // 这里是一个简单的算法,同时也是我个人认为整个程序达到目的的核心。 printf("第%d个出局的人是%d号\n",++x,a[i]); for (j = i + 1; j < n; j++) //因为有人出列,所以它所对应的数组下标就没有了,所以需要把再出列之后所有人的数组下标提前一位。 { a[j - 1] = a[j]; } n--; //新数组生成后,参与游戏的人数-1,即所有的元素总数-1 if (i == n)//终点后,开始起点 { i = 0; } } printf("最后出列的人是%d\n", a[i]); system("pause"); return 0; }绝大多数我还是标了一些注释的,可能会有错别字。233 这个代码整体还是我借鉴了一些前辈的。其中个人觉得比较关键的是
i = (i + m - 1) % n; // 这里是一个简单的算法,同时也是我个人认为整个程序达到目的的核心。 for (j = i + 1; j < n; j++) //因为有人出列,所以它所对应的数组下标就没有了,所以需要把再出列之后所有人的数组下标提前一位。 { a[j - 1] = a[j]; }第一个是整个问题解决的精髓算法(也不知道这个能不能叫做算法,我还没有正式的接触 )。 第二个就是数组的整理。如果用链表来实现的话,就是节点的删除与链表的重新链接(学的不是很好,可能会有错误的说法,希望大佬们指正)。 希望我能早点写出链表实现。