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

(算法篇)自写环形链表解决约瑟夫问题

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

(算法篇)自写环形链表解决约瑟夫问题

约瑟夫问题我这里就不多赘述了,相比你们也看过几篇博客了吧!

以下代码代表创建链表的格式

class Node {
    private int no; // 编号
    private Node next;
    public Node(int no) {
        this.next = null;
        this.no = no;
    }
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }
    public Node getNext() {
        return next;
    }
    public void setNext(Node next) {
        this.next = next;
    }
}

以下代码代表创建循环的链表,并且展示出来

class CircleSinglelinkedList {
    private Node head;
    //添加节点,构建成一个环形链表
    //根据nums创建相应的节点
    public void addNode(int nums) {
        if (nums <= 0) {
            System.out.println("nums的值不正确");
            return;
        }
        Node curNode = null;
        for (int i = 1; i <= nums; i++) {
            Node node = new Node(i);
            if (i == 1) {
                curNode = node;
                this.head = node;
                node.setNext(node);
            }
            else {
                curNode.setNext(node);
                curNode = curNode.getNext();
            }
            if (i == nums) {
                curNode.setNext(this.head);
            }
        }
    }

    public void display() {
        Node cur = this.head;
        if (this.head == null) {
            System.out.println("链表为null");
            return;
        }
        System.out.println(cur.getNo());
        cur = cur.getNext();
        while (cur != this.head) {
            System.out.println(cur.getNo());
            cur = cur.getNext();
        }
    }

以上都是准备工作!

接下来就是解决约瑟夫问题,其实思路很简单,就是通过一个节点,每次走你规定的步数然后进行删除就可以,留下最后一个节点就是结果。那这里我们定义这个节点为first

不过因为这个是单链表(当我们的first走到了需要删除的节点的时候,我们却无法删除它),所以删除的时候需要一个辅助的节点进行帮助删除,并且这个辅助节点就在first的后面一个位置,如果各位学过数据结构的单链表就应该知道了的吧。

那我们直接上代码实现,根据代码后面的详细注释想必你可以轻易的看懂!

public void solveJoseph(int startNo, int countNum, int nums) {
        //startNo 表示从第几个小孩开始数
        // countNum 表示数几下
        // nums表示最初有多少小孩在圈

        // 先判断参数合理性合理性
        if (this.head == null || this.head.getNext() == null || startNo > nums) {
            System.out.println("参数请重新输入");
            return;
        }

        Node helper = this.head;//辅助节点,帮助first进行删除的节点
        Node first = this.head;//指向需要删除的节点
        for (int j = 0; j < startNo - 1; j++) { //让first走到指定的位置
            first = first.getNext();
        }
        while (helper.getNext() != first) { // 让helper指向first的后一个节点
            helper = helper.getNext();
        }
        // 让first与helper指针向前走countNum-1步,然后出圈,知道圈中只有一个节点
        while (helper != first) {
            int n = countNum - 1;
            while (n != 0) {
                helper = helper.getNext();
                first = first.getNext();
                n--;
            }
            System.out.println("出圈的小孩:" + first.getNo());
            first = first.getNext();
            helper.setNext(first);
        }
        System.out.println("最后一个小孩的编号:" + helper.getNo());
    }

以下是主方法里面的内容————————————

CircleSinglelinkedList circleSinglelinkedList = new CircleSinglelinkedList();
        circleSinglelinkedList.addNode(25);
        circleSinglelinkedList.solveJoseph(1,2,25);

结束了,谢谢各位看到这里。

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

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

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