约瑟夫问题(Java单向环形链表)

问题描述

N个人围成一圈,从第K个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。

思路

  1. 本文章介绍使用单向环形链表解决该问题
  2. 创建指定节点个数单向环形列表
  3. 每次报数开始位置记为first节点以及前一节点Help,为了能每次找到并删除第M个节点
  4. 删除后再次刷新first节点,直到剩余一个节点

代码实现

/**
 * 約瑟夫问题
 *
 * @author: ralap
 * @date: created at 2019/6/7 17:40
 */
public class JosephuProblem {

    public static void main(String[] args) {

        JosephuProblem ysf = new JosephuProblem(50);
        ysf.show();
        ysf.solve(4, 8);
    }

    MyNode first;
    private int count;

    public JosephuProblem(int count) {
        this.count = count;
        if (count <= 0) {
            throw new IllegalArgumentException("不支持该参数");
        }
        MyNode node;
        MyNode temp = null;
        for (int i = 1; i <= count; i++) {
            node = new MyNode(i, "Ralap" + i);
            if (temp == null) {
                first = temp = node;
            } else {
                temp.next = node;
                temp = node;
            }
            if (i == count) {
                temp.next = first;
            }
        }
    }

    public void show() {
        MyNode temp = first;
        int showCount = count;
        while (showCount > 0) {
            System.out.println(temp);
            temp = temp.next;
            showCount--;
        }
    }

    public void solve(int beginNum, int step) {

        if (first == null || beginNum <= 0 || step <= 0) {
            return;
        }
        MyNode help = getNode(((beginNum - 2 + count) % count) + 1);
        first = help.next;
        while (true) {
            if (first.no == help.no) {
                System.out.println("--->NO:" + first.no);
                break;
            } else {
                for (int i = 1; i <= step; i++) {
                    first = first.next;
                    help = help.next;
                }
                System.out.println("--->NO:" + first.no);
                first = first.next;
                help.next = first;
            }
        }
    }

    //获取指定位小标节点
    public MyNode getNode(int index) {
        MyNode cur = null;
        int getCount = 1;
        while (getCount <= index) {
            if (getCount == 1) {
                cur = first;
            } else {
                cur = cur.next;
            }
            getCount++;
        }
        return cur;
    }
}

class MyNode {

    public int no;
    public String name;
    public MyNode next;

    public MyNode(int no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public String toString() {
        return "MyNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

你可能感兴趣的:(约瑟夫问题(Java单向环形链表))