求解约瑟夫(Joseph)问题---Java算法小练

约瑟夫问题,是一个计算机科学数学中的问题,在计算机编程算法中,类似问题又称为约瑟夫环,又称“丢手绢问题”。

-百度百科

相信大部分人在刚开始接触Java算法都会遇到约瑟夫问题,约瑟夫问题可以这样理解:

有n个小孩围成一圈,给他们从1开始依次编号,从编号为1的小孩开始报数,数到第m个小孩出列,然后从出列的下一个小孩重新开始报数,数到第m个小孩又出列,…,如此反复直到所有的小孩全部出列为止,求整个出列序列。

用Java算法求解约瑟夫问题,此处用到的是循环单链表模式

代码如下:


public class Joseph {                           //求解约瑟夫问题类
    int n, m;
    Child firstChild;                           //首结点的指针

    public Joseph(int n1, int m1) {             //构造方法,建立有n1个结点的循环单链表
        Child p, t;                             //这里的t指向新建循环单链表的尾结点
        n = n1;                                 //设置数据成员值
        m = m1;                                 //设置数据成员值
        firstChild = new Child(1);          //首先简历no为1的首结点
        t = firstChild;
        if (n < 1) {                            //如果输入的小孩个数不符合常理,那么应该向用户报错
            System.out.println("输入数据错误!");
            return;
        }
        for (int i = 2; i <= n; i++) {
            p = new Child(i);                   //建立一个编号为i的新结点p
            t.next = p;                         //将p结点链到末尾
            t = p;
        }
        t.next = firstChild;                    //构成一个首结点为firstChild的循环单链表
    }

    public String Jesquence() {                 //求解约瑟夫序列
        String answer = " ";
        int i, j;
        Child p, q;
        for (i = 1; i <= n; i++) {              //共列出有n个小孩
            p = firstChild;
            j = 1;
            while (j < (m - 1)) {               //报到第m-1个结点结束
                j++;                            //报数递增
                p = p.next;                     //找到下一个结点
            }
            q = p.next;                         //让q指向第m个结点
            answer += q.no + " ";               //该结点的小孩出列并输出该小孩的编号
            p.next = q.next;                    //删除q结点
            firstChild = p.next;                //从下一结点重新开始
        }
        return answer;
    }
}

class Child {                                   //首先小孩结点类型
    int no;                                     //每个小孩的编号
    Child next;                                 //指向下一个结点的指针

    public Child(int no1) {                     //重载构造方法
        no = no1;
        next = null;
    }
}

那么我们可以开始写测试类了:


public class JosephTest {                           //约瑟夫问题的测试类
    public static void main(String[] args) {
        int n = 6, m = 3;
        Joseph joseph1 = new Joseph(n, m);
        System.out.println("n=" + n + ", m=" + m + "的约瑟夫序列为:" + joseph1.Jesquence());
        n = 8;
        m = 4;
        Joseph joseph2 = new Joseph(n, m);
        System.out.println("n=" + n + ", m=" + m + "的约瑟夫序列为:" + joseph2.Jesquence());
    }
}

输出结果如下:

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值