约瑟夫问题(有时也称为约瑟夫置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。又称“丢手绢问题”。) 约瑟夫问题是个有名的问题:指定一个数M,N个人围成一圈,从第一个开始报数,第M个将出列,然后下一个人又从1开始报数,到M那个人又出列,直到剩下最后一个,其余人都将出列。例如N=6,M=5,则出列的顺序是:5,4,6,2,3,1。 这道题我们使用链式存储和顺序存储两种方式实现。链式存储的数据结构是链表,不懂的可以去看看数据结构的书,顺序存储就用普通的数组即可,下面放代码。
import java.util.Scanner; public class Joseph { public static void main(String[] args) { Scanner in=new Scanner(System.in); int m,n; System.out.println("输入报数号"); m=in.nextInt(); System.out.println("输入个数"); n=in.nextInt(); //.................链式结构 Linkedlist l=new Linkedlist(); for(int i=0;i<n;i++) { l.add(i+1); } l.link(); System.out.print("链式存储结果为"); for(int i=0;i<n;i++) { System.out.print(l.out(m)); } System.out.println(); //................顺序结构 int x=0; Queue q=new Queue(n); int num[]=new int[n+1]; for(int i=0;i<n+1;i++) { num[i]=i; } for(int i=1;i<=n;i++) { for(int j=0;j<m;j++) { x=x+1>n?(x+1)%n:x+1; while(num[x]==0) { x=x+1>n?(x+1)%n:x+1; } } q.push(num[x]); num[x]=0; } System.out.print("顺序存储结果为"); for(int i=0;i<8;i++) { System.out.print(q.pop()); } } } class Linkedlist{//链表存储 int size,x; Node h,r,t; public Linkedlist() { size=0; h=r=t=null; } class Node{ int value; Node link; public Node(int x) { value=x; } } public void add(int x){ Node newHead=new Node(x); if(size==0){ h=r=t=newHead; }else{ r.link=newHead; r=newHead; } size++; } public void link() { r.link=h; } public int out(int m) { for(int i=0;i<m-1;i++) { r=r.link; } x=r.link.value; r.link=r.link.link; return x; } } class Queue{//顺序存储 private int f,r,N; int q[]; public Queue(int N) { this.N=N; f=r=0; q=new int[N]; } public void push(int x) { q[r++]=x; } public int pop() { return q[(f++)%N]; } }