【数据结构与算法】约瑟夫环(C/C++)

这篇具有很好参考价值的文章主要介绍了【数据结构与算法】约瑟夫环(C/C++)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实践要求

1. 问题描述

约瑟夫问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始。按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计程序求出出列顺序。


2. 基本要求

利用单向循环链表存储结构模拟此过程,按照出列的顺序印出个人的编号。


3. 测试数据

3.1 input

  • m = 20
  • n=7
  • 7个人的密码分别为:3,1,7,2,4,8,4

3.2 output

(正确的结果应为6,1,4,7,2,3,5)


实践报告

1. 题目分析

说明程序设计的任务,强调的是程序要做什么,此外列出各成员分工

程序设计任务:解决约瑟夫问题——编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始。按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。最后输出列顺序。


2. 数据结构设计

说明程序用到的数据结构的定义,主程序的流程及各模块之间的层次关系

使用了单向循环链表。定义了一个Person的类(包含了密码(code)、编号(No)、下一个人的指针 Person* next、以及一个构造函数Person(int c, int N) 其中"c"表示当前人的code,"N"表示当前人的编号 )

主程序流程图

【数据结构与算法】约瑟夫环(C/C++),算法与数据结构,C/C++,c语言,c++,算法


3. 程序设计

实现概要设计中的数据类型,对主程序、模块及主要操作写出伪代码,画出函数的调用关系

数据类型

  • vector数组
  • 指针
  • int

主程序操作伪代码

【数据结构与算法】约瑟夫环(C/C++),算法与数据结构,C/C++,c语言,c++,算法


4. 调试分析

程序复杂度分析

1. 空间复杂度
o ( n ) o(n) o(n)
2. 时间复杂度
O ( m + n + ∑ c o d e ) O(m+n+\sum code) O(m+n+code)

心得体会

使用链表要注意不能使用空指针,不能使用指向未知内存的指针,以及用完指针后要及时释放。否则就会碰到一些莫名其妙的错误。


5. 测试结果

列出测试结果,包括输入和输出

测试结果一

input

上限值为20、人数为7、每人的密码分别为3、1、7、2、4、8、4

output

6,1,4,7,2,3,5

【数据结构与算法】约瑟夫环(C/C++),算法与数据结构,C/C++,c语言,c++,算法

测试结果二

input

上限值为30、人数为7、每人的密码分别为3、1、7、2、4、8、4

output

2,3,5,4,7,6,1

【数据结构与算法】约瑟夫环(C/C++),算法与数据结构,C/C++,c语言,c++,算法


6. 用户使用说明

给出主界面及主要功能界面

主界面

【数据结构与算法】约瑟夫环(C/C++),算法与数据结构,C/C++,c语言,c++,算法

使用说明

输入上限值后回车 -> 输入人数后回车 -> 输入每个人的密码后回车 -> 全部密码输入完毕后自动打印出列人员的编号。

7. 附录

源程序文件清单:
JosephusProblem.cpp //主程序

8. 全部代码

/*问题描述
约瑟夫问题的一种描述是:编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始。按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计程序求出出列顺序。
基本要求
利用单向循环链表存储结构模拟此过程,按照出列的顺序印出个人的编号。
测试数据
m的初值为20;n=7,7个人的密码: 3,1,7,2,4,8,4。(正确的结果应为6,1,4,7,2,3,5) 
(报告上要求写出多批数据测试结果
实现提示
程序运行后首先要求用户指定初始报数上限值与人数,然后读取各人的密码*/

#include <iostream>
#include <vector>
using namespace std;

//人类
class Person {
public:
    //密码
    int code;
    //编号
    int No;
    //下一个人的指针
    Person *next = nullptr;
    //构造函数
    Person(int c, int N):code(c), No(N) {
        
    }
};

int main() {
    //下一次要走的步数
    int step;
    //有多少个人
    int num;
    cout << "请输入报数上限值" ;
    cin >> step;
    cout << "请输入总共有多少个人";
    cin >> num;

    //head存循环单链表的头,即编号为1的人的位置;tmp为临时变量,但最后它将存放最后一个人的位置
    Person *head, *tmp;
    //构造循环单链表,这是一个没有头节点的循环单链表
    for(int i = 0; i < num; ++i) {
        int code;
        //读取密码
        printf("请输入第%d个人的密码",i + 1); 
        cin >> code;
        if(i == 0) {
            //head,即第一个人的位置
            head = new Person(code, i + 1);
            tmp = head;
        }else {
            tmp->next = new Person(code, i + 1);
            //更新
            tmp = tmp->next;
        }
    }
    //将尾衔接到头上
    tmp->next = head;

    //start每一次报数开始的位置,随着每个人报数一步步移动
    Person *start = head;
    //前驱指针
    Person *pre = tmp;
    //存放最终结果的序号列表
    vector<int> NoList;
    for(int i = 0; i < num; ++i) {//num次循环,即num次报数
        for(int j = 0; j < step - 1; ++j) {
            //前驱结点更新
            pre = start;
            //随着报数进行,一步步指向下一个人
            start = start->next;
        }//循环结束,指到的人便出列
        //读取密码
        step = start->code;
        //存入序号
        NoList.push_back(start->No);
        //记录一下下一个结点的位置,方便删除此结点,即指到的人出列
        Person *newStart = start->next;
        //删除结点
        pre->next = start->next;
        //释放空间
        delete start;
        //更新
        start = newStart;
    }
    //输出结果
    for(auto i : NoList) {
        cout << i << ' ';
    }
    return 0;
}


结束语

  因为是算法小菜,所以提供的方法和思路可能不是很好,请多多包涵~如果有疑问欢迎大家留言讨论,你如果觉得这篇文章对你有帮助可以给我一个免费的赞吗?我们之间的交流是我最大的动力!文章来源地址https://www.toymoban.com/news/detail-523271.html

到了这里,关于【数据结构与算法】约瑟夫环(C/C++)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言数据结构篇——约瑟夫环的实现

    作者名:Demo不是emo  主页面链接 : 主页传送门 创作初心: 对于计算机的学习者来说,初期的学习无疑是最迷茫和难以坚持的,中后期主要是经验和能力的提高,我也刚接触计算机1年,也在不断的探索,在CSDN写博客主要是为了分享自己的学习历程,学习方法,总结的经验等

    2023年04月08日
    浏览(33)
  • C语言数据结构-用链表解决约瑟夫环问题

    只是普通的大学生一枚,不会很牛的技巧和算法,只是在做数据结构作业中的一点感悟和思考。也不知道自己写得对不对,有什么意见和建议都可以直接指出来哦,我虚心接受(低头鞠躬.jpg)...... 试用线性表的链表存储结构来实现约瑟夫(Josephu)问题。约瑟夫问题如下:设有

    2024年02月06日
    浏览(44)
  • C语言---数据结构实验---顺序表的合并---链表的基本操作---重点解析约瑟夫问题

    实验的写法多种多样,但本文并未采用 #define 定义容量的写法,这样写已经是很老旧过时的写法。所有实验主体采用均为动态开辟,后续如果利用 C++ 来写或许会应用更多语法… 本篇展示数据结构的两个实验 其中,重点分析约瑟夫问题 实验中代码的命名风格等均与下方博客

    2024年02月16日
    浏览(65)
  • 数据结构实验1约瑟夫环

    刚开始m值为20 循环链表

    2024年02月08日
    浏览(42)
  • 【数据结构】使用循环链表结构实现约瑟夫环问题

    目录 1.循环链表的定义 2.约瑟夫环问题 3.创建循环链表 4.删除节点操作 5.打印所有节点 6.实现约瑟夫环问题的完整程序代码 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于CSDN📚。 📣如需转载,请事先与我联

    2024年01月18日
    浏览(39)
  • 数据结构学习-循环链表:处理约瑟夫环问题

    目录 问题描述 一、基本概念  1.普通链表 2.单向循环链表  二、问题处理 1.创建链表 2.查找 3.删除  4.其他  三.实验环节 四.总结 约瑟夫环问题的一种描述是:编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数

    2024年02月07日
    浏览(40)
  • 数据结构实验---顺序表的合并---链表的基本操作---重点解析约瑟夫问题

    实验的写法多种多样,但本文并未采用 #define 定义容量的写法,这样写已经是很老旧过时的写法。所有实验主体采用均为动态开辟,后续如果利用 C++ 来写或许会应用更多语法… 本篇展示数据结构的两个实验 其中,重点分析约瑟夫问题 实验中代码的命名风格等均与下方博客

    2024年02月16日
    浏览(58)
  • 数据结构上机实验——栈和队列的实现、栈和队列的应用、进制转换、约瑟夫环问题

      1.利用栈的基本操作实现将任意一个十进制整数转化为R进制整数。   2.利用循环队列实现.约瑟夫环问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到k的那个人出圈;他的下一个人又从1开始报数,数到k的那个人出圈;依

    2024年02月08日
    浏览(40)
  • 神奇的约瑟夫环(C语言)

    约瑟夫环是一个古老而有趣的问题,它涉及人与人之间的生死较量,引发了人们长久以来的思考和探索。这个问题可以通过不同的方式来解决,每种方式都有其独特的优缺点。 使用数组实现约瑟夫环可以简单直观地表示人员的顺序,但受到数组大小静态限制和数据复制的操作

    2024年02月13日
    浏览(36)
  • C语言:约瑟夫环问题详解

    前言 哈喽,宝子们!本期为大家带来一道C语言循环链表的经典算法题(约瑟夫环)。 据说著名历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被人抓到,于是决定了一个自杀方式,41个人

    2024年04月13日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包