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函数,计算出最后一个出列的人的编号,并输出结果。

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

相关文章
|
6月前
|
算法 C语言
约瑟夫环的C语言和86/88汇编非递归算法
约瑟夫环的C语言和86/88汇编非递归算法
67 0
|
存储 算法 C语言
从古迷题到现代奇迹:神奇的约瑟夫环(C语言)
从古迷题到现代奇迹:神奇的约瑟夫环(C语言)
310 0
C语言 | 数据结构—约瑟夫环问题
目录 首先什么是约瑟夫环 约瑟夫环实现方式 一、创建结构体变量 二、初始化链表 三、构建循环链表 四、删除链表 五、完整代码及注释讲解 首先什么是约瑟夫环 约瑟夫环是循环链表中的一个经典问题;题目描述:n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈; 假设10个人围成一圈,依次编号1到10,按从小到大顺序报数,报到3的人出局,流程示意图如下 约瑟夫环实现方式 我个人倾向于循环链表; 一、创建结构体变量 typedef struct Node{ int data; //数据域 st
C语言 | 数据结构—约瑟夫环问题
|
C语言
C语言数据结构篇——约瑟夫环的实现
C语言数据结构篇——约瑟夫环的实现
220 0
|
C语言
C语言——约瑟夫环问题(链表解决)
问题描述:编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3…这样依次报),数到 m 的 士兵会被杀死出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。
212 0
C语言——约瑟夫环问题(链表解决)
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
33 3
|
6天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
21 6
|
26天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
34 10
|
19天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
25天前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
53 7