最详细解析约瑟夫环算法-两种方法:循环链表和数组

问题描述 约瑟夫环问题是一个很经典的问题:

一个圈共有N个人(N为不确定的数字),第一个人的编号为0或者1(两个都可以,看你的程序如何编写),假设这边我将第一个人的编号设置为1号,那么第二个人的编号就为2号,第三个人的编号就为3号,第N个人的编号就为N号,现在提供一个数字M,第一个人开始从1报数,第二个人报的数就是2,依次类推,报到M这个数字的人出局,紧接着从出局的这个人的下一个人重新开始从1报数,和上面过程类似,报到M的人出局,直到N个人全部出局,请问,这个出局的顺序是什么?

假如有6个人,报2的出局(N = 6,M = 2)

解题关键:理解题目:出局以后数又从头开始报数。

选择方法:圈->循环链表 或者 数组

法1: 循环链表

结构体:作为链表结点,包含两个域,分别是data(数据域)和next(指针域,指向下一个结点),数据域存储每个人的编号,假设从1开始。

typedef int data_t;
typedef struct linklist
{
    data_t data;//数据域
    struct linklist *next;//指针域
}LinkList;

创建头节点head;指向的data p;rear尾指针

//初始化循环链表
  LinkList *head = NULL,*p=NULL,*r=NULL;   //head为头指针,指向链表的第一个结点,一开始赋值为NULL,代表不指向任何结点 
  head = (LinkList*)malloc(sizeof(LinkList));  //让head指向一个实际的空间
  if(NULL==head)  //内存空间可能会申请失败,大多数情况不会申请失败 
  {
      cout << "Memory Failed!";
      return;
  } 
  head->data=1;       //从1开始编号 
  he
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值