C语言解决约瑟夫环问题

简介: C语言解决约瑟夫环问题

约瑟夫环问题是一个经典的数学问题,它的描述如下:有n个人围成一圈,从第1个人开始报数,数到第m个人出列,然后从出列的下一个人开始重新报数,数到第m个人出列,如此循环,直到最后一个人出列为止。本文将介绍如何使用链表来解决这个问题。

链表是一种数据结构,它由一系列节点组成,每个节点包含一个值和一个指针,指向下一个节点。链表的优点是可以动态地添加和删除元素,因此非常适合解决约瑟夫环问题。

我们可以使用单向循环链表来模拟约瑟夫环。具体来说,我们可以先创建一个包含n个节点的单向循环链表,每个节点表示一个人,然后从第一个节点开始一次遍历链表,每次遍历m个节点,并将当前节点从链表中删除。当链表中只剩下一个节点时,该节点即为最后一个出列的人。

以下是约瑟夫环问题的具体实现代码:

#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
struct node {
    int value;
    struct node *next;
};
// 创建一个包含n个节点的单向循环链表
struct node *create_list(int n) {
    struct node *head = NULL;
    struct node *current = NULL;
    for (int i = 1; i <= n; i++) {
        struct node *new_node = (struct node *)malloc(sizeof(struct node));
        new_node->value = i;
        new_node->next = NULL;
        if (head == NULL) {
            head = new_node;
        } else {
            current->next = new_node;
        }
        current = new_node;
    }
    current->next = head;
    return head;
}
// 解决约瑟夫环问题
int josephus(int n, int m) {
    struct node *head = create_list(n);
    struct node *current = head;
    while (current->next != current) {
        for (int i = 1; i < m; i++) {
            current = current->next;
        }
        struct node *temp = current->next;
        current->next = current->next->next;
        free(temp);
    }
    int result = current->value;
    free(current);
    return result;
}
int main() {
    int n = 10;
    int m = 3;
    int result = josephus(n, m);
    printf("The last person is %d\n", result);
    return 0;
}

在上面的代码中,create_list函数用于创建一个包含n个节点的单向循环链表,josephus函数用于解决约瑟夫环问题,并返回最后一个出列的人的编号。最后,我们在主函数中调用josephus函数,计算出最后一个出列的人的编号,并输出结果。

总结来说,使用链表解决约瑟夫环问题是一种非常简单、高效的方法。在实际的编程中,我们可以根据实际情况对链表节点的结构进行调整,以便更好地满足具体的需求。

相关文章
|
8月前
|
算法 C语言
约瑟夫环的C语言和86/88汇编非递归算法
约瑟夫环的C语言和86/88汇编非递归算法
84 0
|
存储 算法 C语言
从古迷题到现代奇迹:神奇的约瑟夫环(C语言)
从古迷题到现代奇迹:神奇的约瑟夫环(C语言)
349 0
C语言 | 数据结构—约瑟夫环问题
目录 首先什么是约瑟夫环 约瑟夫环实现方式 一、创建结构体变量 二、初始化链表 三、构建循环链表 四、删除链表 五、完整代码及注释讲解 首先什么是约瑟夫环 约瑟夫环是循环链表中的一个经典问题;题目描述:n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈; 假设10个人围成一圈,依次编号1到10,按从小到大顺序报数,报到3的人出局,流程示意图如下 约瑟夫环实现方式 我个人倾向于循环链表; 一、创建结构体变量 typedef struct Node{ int data; //数据域 st
C语言 | 数据结构—约瑟夫环问题
|
C语言
C语言——约瑟夫环问题(链表解决)
问题描述:编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3…这样依次报),数到 m 的 士兵会被杀死出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。
226 0
C语言——约瑟夫环问题(链表解决)
|
C语言
C语言数据结构篇——约瑟夫环的实现
C语言数据结构篇——约瑟夫环的实现
231 0
|
2天前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
25 15
|
2天前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
38 24
|
2天前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
39 23
|
1天前
|
存储 编译器 C语言
【C语言程序设计——函数】回文数判定(头歌实践教学平台习题)【合集】
算术运算于 C 语言仿若精密 “齿轮组”,驱动着数值处理流程。编写函数求区间[100,500]中所有的回文数,要求每行打印10个数。根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码。如果操作数是浮点数,在 C 语言中是不允许直接进行。的结果是 -1,因为 -7 除以 3 商为 -2,余数为 -1;注意:每一个数据输出格式为 printf("%4d", i);的结果是 1,因为 7 除以 -3 商为 -2,余数为 1。取余运算要求两个操作数必须是整数类型,包括。开始你的任务吧,祝你成功!
15 1
|
1月前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
75 10