栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【恋上数据结构】约瑟夫问题(循环链表解决)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【恋上数据结构】约瑟夫问题(循环链表解决)

练习-约瑟夫问题

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

分析:

(1)由于对于每个人只有死和活两种状态,因此可以用布尔型数组标记每个人的状态,可用true表示死,false表示活。

(2)开始时每个人都是活的,所以数组初值全部赋为false。

(3)模拟杀人过程,直到所有人都被杀死为止。

为了活到最后,我们只能写个算法来帮我们算了!!

思路:

  • 使用循环链表
  • 用一个指针,用于指向节点
  • 增加一个reset方法,重置指针指向头结点
  • 增加一个next方法,让指针往后走一步
  • 增加一个remove方法,用于杀死指针指向的节点,删除后指向下一个节点。
public class JosephusProblem {
    public static void main(String[] args) {
       josephus(3,8);
    }

    
    public static void josephus(int m,int people){
        CirclelinkedList list = new CirclelinkedList<>();
        for (int i = 1; i <= people; i++) {
            list.add(i);
        }
        System.out.println(list.toString());
        //指向头结点
        list.reset();
        //循环杀
        while(! list.isEmpty()){
            for (int i = 1; i < m; i++) {
                list.next();
            }
            System.out.println(list.remove());
        }
    }
}

package 链式结构.test;

import common.AbstractList;


public class CirclelinkedList {
    
    private Node first;
    
    private Node last;
    
    private Node current;

    
    private static class Node {
        E element;
        Node prev;
        Node next;
        public Node(Node prev, E element, Node next) {
            this.prev = prev;
            this.element = element;
            this.next = next;
        }
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            if (prev != null) {
                sb.append(prev.element);
            } else {
                sb.append("null");
            }
            sb.append("_").append(element).append("_");

            if (next != null) {
                sb.append(next.element);
            } else {
                sb.append("null");
            }
            return sb.toString();
        }
    }
    

    
    public void reset(){
        current = first;
    }

    
    public E next(){
        if (current == null){
            return null;
        }
        current = current.next;
        return current.element;
    }

    
    public E remove(){
        if(current == null){return null;}
        Node next = current.next;
        E element = remove(current);
        if (size == 0) {
            current = null;
        } else {
            current = next;
        }

        return element;
    }
    private E remove(Node node) {
        if (size == 1) {
            first = null;
            last = null;
        } else {
            Node prev = node.prev;
            Node next = node.next;
            prev.next = next;
            next.prev = prev;

            if (node == first) { // index == 0
                first = next;
            }

            if (node == last) { // index == size - 1
                last = prev;
            }
        }

        size--;
        return node.element;
    }

    public void add(int index, E element) {
        rangeCheckForAdd(index);

        // size == 0
        // index == 0
        if (index == size) { // 往最后面添加元素
            Node oldLast = last;
            last = new Node<>(oldLast, element, first);
            if (oldLast == null) { // 这是链表添加的第一个元素
                first = last;
                first.next = first;
                first.prev = first;
            } else {
                oldLast.next = last;
                first.prev = last;
            }
        } else {
            Node next = node(index);
            Node prev = next.prev;
            Node node = new Node<>(prev, element, next);
            next.prev = node;
            prev.next = node;

            if (next == first) { // index == 0
                first = node;
            }
        }

        size++;
    }

    
    private Node node(int index) {
        rangeCheck(index);

        if (index < (size >> 1)) {
            Node node = first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            return node;
        } else {
            Node node = last;
            for (int i = size - 1; i > index; i--) {
                node = node.prev;
            }
            return node;
        }
    }
    

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/684318.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号