约瑟夫环问题
问题描述:假设有N个小孩按照序号1,2,,,N围坐成一圈,从第一个小孩开始报数,每次报到n的人退出,接着从下一个人重新开始从1开始报数,下一次再报到n的人退出,求最后一个留下的人;
数组实现:
public class huan { /** * @param args */ public static void main(String[] args) { String[] s = new String[]{"0a","1b","2c","3d","4e","5f","6g","7h","8i","9j","10k","11l","12m","13n","14o","15p"}; int k = 3; while(s.length != 0){ int i = 1; while(i <= 2){ if(++k > s.length-1) {//循环n次的时候,每次递增时进行下表越界判断 或者k=k%(s.length) k = 0; } if(s[k] != null) { i++; } } System.out.print(s[k] + ' '); s[k] = null; } } }
输出:5f 7h 9j 11l 13n 15p 1b 3d 6g 10k 14o 2c 8i 0a 12m 4e
循环链表实现:
package com.iteye.ljmdbc7a; import java.util.Scanner; /** * 循环列表的Java实现,解决约瑟夫环问题 * @author LIU * */ public class LinkedList { //定义结点,必须是static static class Node { int data; Node next; Node(int arg1) { this.data = arg1; } } public static void main(String[] args) { int n = 0,m = 0;//定义总人数n,和出圈数字m //输入n和m System.out.println("输入总人数n,出圈数字m"); Scanner scanner = new Scanner(System.in); n = scanner.nextInt(); m = scanner.nextInt(); //初始化循环列表,头结点first和尾结点p Node first = new Node(1); first.next = first; Node p = first; for(int i=2; i<=n; i++) { Node temp = new Node(i); temp.next = p; p.next = temp; p = p.next; } p.next = first;//尾接头形成循环链表(p为尾结点) //执行出圈操作 System.out.println("出圈顺序为:"); while(p != p.next) { //下面for循环后,p是第m个结点的前一个结点 for(int i=1; i<m; i++) p = p.next; //删除第m个结点 System.out.print(p.next.data+" "); p.next = p.next.next; } System.out.print("\n幸运者是:"+p.data); } }