14、约瑟夫环

6人阅读 评论(0) 收藏 举报
分类:

已知n个人围坐在一张圆桌周围,从编号为1的人开始报数,数到m的那个人出列。下一个人从1开始报数,数到m的人继续出列,以此类推直至全部人出列。求出列顺序?

解决方案:

1、最简单明了的办法就是用循环链表存储这n个人。数到m的人出列,只需将该结点从链表里剔除即可,然后继续往后报数,直到链表只剩下一个结点时结束。

具体代码如下:

typedef struct People  
{  
    int number;  
    People *next;  
}//结点的存储结构  

void List_kind(People* L,int n,int m)  
{/////////////////////////////////////////////L为n个人构成的链表,报数报到m的人出列  
    People *q,*p=L;///////////////////////////p指向当前结点,q指向p的前驱  
    while(p->next != p)///////////////////////当链表只剩下一个结点,即报数剩下一个人的时候结束。  
    {  
        for(int i=1;i<m;i++)  
        {/////////////////////////////////////for循环实现功能:使p指向要出列的结点,q指向p的前驱  
            q=p;  
            p=p->next;  
        }  
        printf("%d\n",p->number);  
        q->next=p->next;//////////////////////将要出列的结点从链表“剔除”  
        free(p);  
        p=q->next;////////////////////////////p指向出列的下一个结点,重新开始报数  
    }  
    printf("%d\n",q->number);/////////////////输出最后一个人  
    free(q);  
} 

第二种办法就是用数组存储,难度将大大增加。但思路还是跟链表有点相似的。首先将要出列的元素输出,然后将它后面的所有元素都向前移一位,将已出列的元素填充掉。然后再向后找下一个要出列的元素。

注意:当搜索到最后一个元素a[i]以后,用求余”%”功能,让数组和循环链表一样实现循环。另外,每次输出一个元素并把它填充掉以后,数组的总元素个数i会减一。

void Array_kind(int n,int m)  
{/////////////////////////////////////////////////////////n个人进行报数,报到m的出列  
    int *a,i,j,k;  
    a=(int*)malloc(sizeof(int));//////////////////////////为数组a动态分配内存  
    for(i=1;i<=n;i++)  
        a[i]=i;///////////////////////////////////////////对每个元素进行编号,代表每个人,注意编号从a[1]开始  
    for(i=n,k=1;i>=1;i--)/////////////////////////////////i为数组当前元素总个数  
    {  
        k=(k+m-1)%i;//////////////////////////////////////令k指向要出列的元素  
        if(k==0)//////////////////////////////////////////从上式知,当k+m-1=i时才会(k+m-1)%i=0。因为数组是从a[1]开始的,k=0时出列的元素应该是a[i],而不是a[0]。  
            k=i;  
        printf("%d\n",a[k]);//////////////////////////////输出要出列的元素  
        for(j=k;j<i;j++)//////////////////////////////////k之后的元素都向前移一位,填充出列元素的位置。  
            a[j]=a[j+1];  
    }  
} 


java实现,使用链表进行移除:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Yue {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入总人数:");
        int totalNum = scanner.nextInt();
        System.out.print("请输入报数的大小:");
        int cycleNum = scanner.nextInt();
        yuesefu(totalNum, cycleNum);
        scanner.close();
    }

    public static void yuesefu(int totalNum, int countNum) {
        // 初始化人数
        List<Integer> start = new ArrayList<Integer>();
        for (int i = 1; i <= totalNum; i++) {
            start.add(i);
        }
        // 从第K个开始计数
        int k = 0;
        while (start.size() > 0) {
            k = k + countNum;
            // 第m人的索引位置
            k = k % (start.size()) - 1;
            // 判断是否到队尾
            if (k < 0) {
                System.out.println(start.get(start.size() - 1));
                start.remove(start.size() - 1);
                k = 0;
            } else {
                System.out.println(start.get(k));
                start.remove(k);
            }
        }
    }
}
查看评论

算法导论思考题14-2 Josephus permutation 约瑟夫排列

约瑟夫问题的定义:假设n个人排成环形,且有一个正整数 m 就让其出列,且报数进行下去。这个过程一直进行到所有人都出列为止。每个人出列的次序定义了整数0,1,2,...n-1 的(n, m)-约...
  • u012839273
  • u012839273
  • 2017-07-05 11:39:48
  • 279

约瑟夫环问题的几种解法

一、问题的来历     据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲在一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于...
  • ltxiaobing
  • ltxiaobing
  • 2015-12-27 14:55:46
  • 1991

C++第15周项目3 -约瑟夫环

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565,本周题目链接:http://blog.csdn.net/sxhelijia...
  • sxhelijian
  • sxhelijian
  • 2013-06-08 07:22:41
  • 6985

史上最全的约瑟夫环算法程序和原理

数学算法:#include "stdio.h"#include "stdlib.h"int josephus(int n, int m){    int pos;    if (n == 1) {  ...
  • ZhengKarl
  • ZhengKarl
  • 2010-05-15 21:47:00
  • 33071

MFC约瑟夫环

  • 2008年01月08日 22:06
  • 1.84MB
  • 下载

最简化约瑟夫环问题的递归算法详细解析

这个问题可能每个学算法的同学都会遇见,我没那么聪明,第一次看见时做不出来,只发现一些规律,后面看到算法也挺久才看懂,这里是将别人的算法结果做一个解析,例子是暂时网上找的递归最简洁的例子: 下面就以这个...
  • m15682532244
  • m15682532244
  • 2017-10-21 15:54:28
  • 597

约瑟夫环C++实现很经典的做法

原文地址:http://www.cnblogs.com/hanxi/archive/2012/10/10/2718413.html /* *******循环链表解决约瑟夫环问题******* * 问...
  • jzh1988903
  • jzh1988903
  • 2014-10-07 14:52:20
  • 2929

约瑟夫环问题--递归推导

本文为学习《剑指offer》的记录。因其原理在原作者博客上找不到,所以,只能自己编写记录,如有不当之处,欢迎指正。题目描述: n个数,编号为 0 , 1, ……, n-1 排成一个圆圈,从数字 0 ...
  • u014613043
  • u014613043
  • 2016-03-16 15:43:23
  • 1367

约瑟夫环约瑟夫环约瑟夫环

  • 2009年10月06日 23:51
  • 2KB
  • 下载

约瑟夫环的问题解决方法与分析

约瑟夫环的问题 相信大家都听过约瑟夫环的问题,据说著名犹太历史学家 Josephus有过以下的故事: 在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹 太人...
  • Dawn_sf
  • Dawn_sf
  • 2017-02-25 11:15:24
  • 1548
    个人资料
    持之以恒
    等级:
    访问量: 5055
    积分: 809
    排名: 6万+
    博客专栏
    文章存档
    最新评论