C语言实现约瑟夫环

约瑟夫环实验报告

                                                                                 报告人:又是一个新的人类?

(一)实验描述和要求

实验描述: 已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
实验要求:

  • 实验①

单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号.
测试数据:m的初值为20;n=7,7个人的密码以此为:3,1,7,2,4,8,4 最先的m值为6
(也就是说这种情况是数字题目给定)

  • 实验②

顺序存储(数组) 方式实现
测试数据:密码m可以任意(正、负均可,不是事先存储,每次运行随机产生)

(二)主要仪器设备

CLion 、 VS (恕我直言,clion我没跑出过一次,用它是因为复制粘贴写出的代码好看)

(三)实验简述

1.一群人围在一起坐成 环状(如:N)
2.从某个编号开始报数(如:K)
3.数到某个数(如:M)的时候,此人出列,下一个人重新报数
4.一直循环,直到所有人出列 ,约瑟夫环结束

(四)实验步骤与调试分析

实验思路
(实验①)用单项循环链表实现 :

1.从编号k开始(k=6)报数,那么顺序应该是4 6 5 3 7 1 2
2.一群人围成环状,则可以用单向循环链表实现,这个比较好理解
3.循环条件是圈内的人数大于1,即while(p->next!=p)指针实现

(实验②)用顺序储存的方式(数组)实现:
刚开始写起来困难是因为没有掌握循环数组的方法 有一个要记下的公式
错误思想是每一次数完后删除该数重新排一次再数
现在想起来就伤心,这样需要用后一个去代替前一个来删除已经报完的数字,时间复杂度很高

所以简便方法是用数组表达一个利用公式 (i+m-1) %n,找出要输出数组的下标i
删除操作可以把这个数字换成产生的随机数之外的数字

1.每个人的密码存放在一个数组 a 中,主函数中决定人数的个数以及报数的上限值 m,设计一个函数实现对应的操作。函数的形参有整型数组 a、整数 n 和 m,
2.n 用来接收传递的人数,m 用来接收报数上限,函数的返回值为空;函数体中输出出列人的顺序。
3. 函数中利用循环访问数组中 n 个元素,每次访问元素,设定内循环连续访问 m 个元素,元素访问的下标为 k,访问到第 m 个元素时,如果元素不是 101,此时输出元素 a[k],再设定 a[k] 为
101,继续访问后面的元素。(用101的原因是在产生的随机数之外)

针对实验①
在这里插入链表的相关操作(熟悉操作的小伙伴们可以直接跳过
1)规范的构建一个新的循环单链 // 副标题 《如何让老师认为自己已经掌握数据结构之格式写标准》

循环单链表和双链表都是只要掌握好单链表的基本操作就可以了

#include<stdio.h>
#include<stdlib.h>
Typedef struct LNode {
   
     ElemType         data;      //数据域
     struct LNode   *next;      //指针域
}LNode, *LinkList;             // *LinkList为LNode类型的指针

细节注意,双链表: ‘ DuL‘

typedef    struct  DuLNode{
   
       ElemType           data;          //数据域
     struct DuLNode  *prior;       //前驱指针域
     struct DuLNode  *next;        //后继指针域
} DuLNode , *DuLinkList ; 

2)单链表的建立有两种方法:头插法和尾插法
头插法

void CreateListF(LinkList *&L, ElemType a[ ], int n)
{
   
    LinkList *s; int i;
    L = (LinkList *)malloc(sizeof (LinkList) ); //创建头结点
    L->next = NULL;     //空链表
    for (i=0; i<n; i++){
   
        s = (LinkList *) malloc (sizeof(LinkList)); //创建新结点
        s->data = a[<
  • 9
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值