数据结构与算法

05-约瑟夫-环形链表

2022-06-21  本文已影响0人  紫荆秋雪_文

铭记:

\color{#DC143C}{算法 + 数据结构 = 程序}

源码下载

背景

约瑟夫问题,是一个计算机科学数学中的问题,在计算机编程算法中,类似问题又称为约瑟夫环,又称“丢手绢问题”
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=3,被杀掉的顺序是:3,6,4,2,5,1。

初始数据.png 第一次报数-找到3.png 第二次报数-找到6.png 第三次报数-找到4.png 第四次报数-找到2.png 第五次报数-找到5.png

解决思路

定义两个辅助变量,一个currentNode指向第一个节点,一个lastNode指向最后一个节点。它们之间的关系为:lastNode.next = currentNode。当 lastNode = currentNode 时代表只有一个节点,直接输出,退出循环。


image.png

代码

package com.raven.alg.s3linked;

/**
 * 约瑟夫
 */
public class Joseph {
    // head
    private Boy head;


    public Joseph() {
    }

    /**
     * 初始化数据
     */
    public Joseph(Integer maxSize) {
        Boy first = null;
        for (Integer i = 1; i <= maxSize; i++) {
            Boy boy = new Boy(i);
            if (null == this.head) {
                this.head = boy;
                first = this.head;
            } else {
                first.next = boy;
                Boy next = first.next;
                first = next;
            }
            // 新增boy的 next 执行 head
            boy.next = this.head;
        }

    }

    /**
     * 约瑟夫输出数据顺序
     *
     * @param start
     * @param step
     */
    public void run(Integer start, Integer step) {
        if (null == this.head) {
            System.out.println("约瑟夫链表为空!!!");
            return;
        }
        // 当前节点
        Boy currentNode = this.head;
        // 最后节点,lastNode.next = currentNode,当 lastNode = currentNode 时代码只有一个
        Boy lastNode = this.getLast();

        // 通过 start 来指定节点位置
        for (Integer i = 1; i < start; i++) {
            currentNode = currentNode.next;
            lastNode = lastNode.next;
        }

        while (true) {
            // 最后一个
            if (currentNode == lastNode) {
                System.out.println("输出数据:" + currentNode);
                break;
            }
            for (Integer i = 1; i < step; i++) {
                currentNode = currentNode.next;
                lastNode = lastNode.next;
            }
            // 找到数据
            System.out.println("输出数据:" + currentNode);
            currentNode = currentNode.next;
            lastNode.next = currentNode;
        }
    }

    /**
     * 输出链表
     */
    public void list() {
        if (null == this.head) {
            System.out.println("约瑟夫链表为空!!!");
            return;
        }
        Boy head = this.head;
        while (true) {
            System.out.println(head);
            if (this.head == head.next) {
                break;
            }
            head = head.next;
        }
    }

    public Boy getLast() {
        if (null == this.head) {
            System.out.println("约瑟夫链表为空!!!");
            return null;
        }
        Boy head = this.head;
        while (true) {
            if (this.head == head.next) {
                return head;
            }
            head = head.next;
        }
    }
}

class Boy {
    Integer no;
    Boy next;

    public Boy(Integer no) {
        this.no = no;
    }

    @Override
    public String toString() {
        return "no=" + no;
    }
}
    /**
     * 约瑟夫问题
     */
    private static void josephTest() {
        Joseph joseph = new Joseph(3);
        joseph.list();
        joseph.run(3, 3);
    }
上一篇下一篇

猜你喜欢

热点阅读