欢迎使用CSDN-markdown编辑器

来源:互联网 发布:淘宝stefano ricci皮带 编辑:程序博客网 时间:2024/06/02 01:59

Josephu问题(丢手帕问题)

Josephu问题为:设编号为1,2,...n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。看了网上的视频,韩顺平老师的JAVA从入门到精通,根据老师给的思路写的代码。
程序入口类
public class DiuShouJuan {    public static void main(String[] args) {        // TODO Auto-generated method stub        LianBiao lb=new LianBiao();        lb.SetLen(7);        lb.SetK(4);        lb.SetM(2);        lb.createLiaoBiao();        lb.show();        lb.play();      }}
对玩游戏的人赋予编号class People{    int num;    People nextPeople=null;    //人的编号    public People(int num){        this.num=num;    }}
//环形链表class LianBiao{    People firstPeople=null;    People temp=null;    int len=0;    int m=0;    int k=0;    public void SetLen(int len){        this.len=len;    }    public void SetM(int m){        this.m=m;    }    public void SetK(int k){        this.k=k;    }    public void play(){        People temp =firstPeople;        //1.第几个人开始数        for(int i=1;i<k;i++){            temp=temp.nextPeople;        }        //2.数m个数        while(len!=1){        for(int j=1;j<m;j++){            temp=temp.nextPeople;        }        System.out.println("第" + temp.num + "个人退出游戏");        //3.第m个人退出游戏        People temp2=temp;        while(temp2.nextPeople!=temp){            temp2=temp2.nextPeople;        }        temp2.nextPeople=temp.nextPeople;        temp=temp.nextPeople;        len--;        }        System.out.print("最后一个:"+temp.num);    }    //创建链表    public void createLiaoBiao(){        for(int i=1;i<=len;i++){            if(i==1){                People p=new People(i);                this.firstPeople=p;                this.temp=p;            }else{                if(i==len){                    People p=new People(i);                    temp.nextPeople=p;                    temp=p;                    temp.nextPeople=firstPeople;                }else{                    People p=new People(i);                    temp.nextPeople=p;                    temp=p;                }            }        }    }    public void show(){        People temp=this.firstPeople;        do{            System.out.print(temp.num+"  ");            temp=temp.nextPeople;        }while(temp!=this.firstPeople);    }}
思路

用一个不带头结点的循环链表来处理Josephu问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点的人从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。
链表的创建在这里还是挺重要的,上述代码中的链表是单向的,所以第一个位置和最后一个位置的,比较重要,而且指向第一个小孩的引用,不能动。

            if(i==1){                People p=new People(i);                this.firstPeople=p;                this.temp=p;            }

嗯就是这样=-=

原创粉丝点击