关于学习韩顺平java学习视频心得

约瑟夫问题()

这是17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。

*问题分析与算法设计

约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多。这里给出一种实现方法。

题目中30个人围成一圈,因而启发我们用一个循环的链来表示。可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。这个是愿意。

现在的衍生问题

就是说有n个人围成一圈,然后说从任意指定的一个

人那里为起点,以m个人为单位,每转m个人第m个人被杀死。当起始人也就是所谓的

1个人是最后被杀死的,这个m就是为所求,满足这样就叫joseph问题。

然后带一个递归实现

学习代码

/*
 * 作者:

 * 功能:丢手帕问题
 */
public class Josiefu {
public static void main(String args[])
{
 CycLink cyclink=new CycLink();
 cyclink.setLen(9);
 cyclink.createLink();
 cyclink.setK(2);
 cyclink.setM(2);
 cyclink.show();
 cyclink.play();
 
 }
}

class Child
{
 int no;
 //创建第一个小孩的引用不能动
 Child nextChild=null;

 public Child(int no)
 {
  this.no=no;//给一个编号
 }
 }
class CycLink
{// 先定义一个指向链表第一个小孩的引用
 Child firstchild=null;
 Child temp=null;
 int len=0;//表示小孩子的个数
 int k=0;
 int m=0;
 //设置链表的大小
 public void setLen(int len)
 {
  this.len=len; 
 }
 //初始化环形链表
 public void createLink()
 {
  for(int i=1;i<=len;i++)
  {
   if(i==1){//创建第一个小孩
    Child ch=new Child(i);
    this.firstchild=ch;
    this.temp=ch;
  }else
  {
   //创建最后的一个小孩
   if(i==len){
    Child ch=new Child(i);
    temp.nextChild=ch;
    temp=ch;
    temp.nextChild=this.firstchild;
    
   }else{
   //继续创建小孩
   Child ch=new Child(i);
   temp.nextChild=ch;
   temp=ch;
   
   }
  }
   
  }
 }
 //设置从第几个人开始数数
 public void setK(int k)
 {
  this.k=k;
 }
 public void setM(int m){
  this.m=m;
  
 }
//开始Play
 public void play()
 {    Child temp=this.firstchild;
  //1.先找到开始数数的人
  for(int i=1;i<k;i++)
  {
   temp=temp.nextChild;
  }
  
   //2.数m下
  while(this.len!=1){
  for(int j=1;j<m;j++)
  {
   temp=temp.nextChild;
  }
  //找到要出圈的前一个小孩
  Child temp2=temp;
  while (temp2.nextChild!=temp)
  {
   temp2=temp2.nextChild;
  }
  //3.将数到m的小孩,退出圈
 temp2.nextChild=temp.nextChild;
 //让temp指向下一个数数的小孩
 temp=temp.nextChild;
 //this.show();
 this.len--;
 //
 }//最后一个小孩
 System.out.println("最后出圈:"+temp.no +"");
 }
 
//打印该环形链表
 public void show()
 {
  //定义一个跑龙套
  Child temp=this.firstchild;
  do{
   System.out.println(+temp.no+"  ");
   temp=temp.nextChild;
  }while(temp!=this.firstchild);
 }

 }

遇到的问题有

java.lang.NullEception的错误,因出现了空指针,把初始化的child的第一个孩子指向了空。出现异常。修改

把初始化的方法中的创建的对象ch的值赋给第一个孩子。

还有//this.show()这个方法出现在循环中出现了死循环!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值