标签:
* 约瑟芬问题,俗称丢手帕问题:
* 有n个人围成一圈,从指定的第一个人开始从1依次报数,
* 数到m的那个人出列,接着下一个人从1开始接着报数,
* 直到最后只剩下一个人出列,问最后出列的是第几个人?
1.单链表解决:
1 /** 2 * 结点类 3 * @author Administrator 4 * @since 2015年8月8日 下午4:10:20 5 * @version 6 * @since JDK 1.6 7 */ 8 class Node{ 9 private int val; 10 private Node next; 11 public int getVal() { 12 return val; 13 } 14 public void setVal(int val) { 15 this.val = val; 16 } 17 public Node getNext() { 18 return next; 19 } 20 public void setNext(Node next) { 21 this.next = next; 22 } 23 }
1 /** 2 * 采用单向链表解决 3 * @author Administrator 4 * @since 2015年8月8日 下午4:05:05 5 * @version 6 * @since JDK 1.6 7 */ 8 class Way1{ 9 private int serialNo=1; 10 private Node head;//定义一个头指针,并非是第一个结点 11 12 public void createLink(int n){//创建链表——约瑟夫环 13 head=new Node(); 14 head.setNext(null); 15 Node rear=new Node(); 16 rear=head; 17 for(int i=0;i<n;i++){ 18 Node newNode=new Node(); 19 newNode.setVal(i+1); 20 newNode.setNext(null); 21 rear.setNext(newNode); 22 rear=newNode; 23 } 24 } 25 26 public void printLink(){ 27 Node p=head.getNext(); 28 System.out.print("约瑟夫环:"); 29 while(p!=null){ 30 System.out.print(p.getVal()+"->"); 31 p=p.getNext(); 32 } 33 System.out.println("end"); 34 } 35 36 /** 37 * 解约瑟夫环 38 * @param startIndex 第一开始报数的人序号 39 * @param count 计数 for 出列 40 */ 41 public void display(int startIndex,int count){ 42 Node p=head; 43 for(int i=0;i<startIndex;i++){//移动到第一个开始报数的人的位置 44 p=p.getNext(); 45 } 46 47 while(head.getNext()!=null){ 48 for(int j=0;j<count-2;j++){ 49 p=p.getNext(); 50 if(p==null){ 51 p=head.getNext(); 52 } 53 } 54 delete(p);//删除p的后继结点 55 if(p.getNext()==null){ 56 p=head.getNext(); 57 }else{ 58 p=p.getNext(); 59 } 60 } 61 62 63 } 64 65 /** 66 * @param p 67 */ 68 private void delete(Node p) { 69 Node q=p.getNext(); 70 if(q==null){//p是尾结点,删除第一个结点 71 Node outman=head.getNext(); 72 head.setNext(outman.getNext()); 73 System.out.println("序号"+(serialNo++)+"-----第"+outman.getVal()+"个人出列"); 74 }else{ 75 p.setNext(q.getNext()); 76 System.out.println("序号"+(serialNo++)+"-----第"+q.getVal()+"个人出列"); 77 } 78 79 } 80 }
2.循环链表解决:
1 /** 2 * 采用循环链表解决 3 * @author Administrator 4 * @since 2015年8月8日 下午5:23:04 5 * @version 6 * @since JDK 1.6 7 */ 8 class Way2{ 9 private Node head;//头指针 10 private int serialNo=1; 11 12 public void createLink(int n){ 13 head=new Node(); 14 head.setNext(null); 15 Node rear=new Node(); 16 rear=head; 17 for(int i=0;i<n;i++){ 18 Node newNode=new Node(); 19 newNode.setVal(i+1); 20 newNode.setNext(head); 21 rear.setNext(newNode); 22 rear=newNode; 23 rear.setNext(head.getNext()); 24 } 25 } 26 27 28 public void printLink(){ 29 Node p=head.getNext(); 30 do{ 31 System.out.print("约瑟夫环:"+p.getVal()+"->"); 32 p=p.getNext(); 33 }while(p!=head.getNext()); 34 System.out.println("end"); 35 } 36 37 /** 38 * 解约瑟夫环 39 * @param startIndex 第一开始报数的人序号 40 * @param count 计数 for 出列 41 */ 42 public void display(int startIndex,int count){ 43 Node p=head; 44 for(int i=0;i<startIndex;i++){ 45 p=p.getNext(); 46 } 47 while(head.getNext()!=null){ 48 for(int j=0;j<count-2;j++){ 49 p=p.getNext(); 50 } 51 delete(p);//delete the rear node of p 52 p=p.getNext(); 53 } 54 } 55 56 57 /** 58 * @param p 59 */ 60 private void delete(Node p) { 61 Node q=p.getNext(); 62 63 if(p==q){ 64 head.setNext(null); 65 System.out.println("序号"+(serialNo++)+"-----第"+q.getVal()+"个人出列"); 66 }else if(q==head.getNext()){ 67 head.setNext(q.getNext()); 68 p.setNext(head.getNext()); 69 System.out.println("序号"+(serialNo++)+"-----第"+q.getVal()+"个人出列"); 70 }else{ 71 p.setNext(q.getNext()); 72 System.out.println("序号"+(serialNo++)+"-----第"+q.getVal()+"个人出列"); 73 } 74 } 75 76 }
标签:
原文地址:http://www.cnblogs.com/davidxu/p/4715114.html