单向环形链表

单向环形链表(Josepfu)

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)按顺时针方向围坐在一张圆桌周围,每个人持有一个密码(正整数)。一开始任选一个整数作为报数上限值m,从第一个人开始顺时针自1报数,报到m时停止报数,报m的那个人出列,他的密码作为新的m值,从他在顺时针方向上的下一个人又开始重新从1报数,报到m的那个人出列又出列;依此规律重复下去,直到圆桌周围的人全部出列

/*
约瑟夫问题
 */
public class Josepfu {
    public static void main(String[] args) {
        //测试
        CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
        circleSingleLinkedList.addBoy(5);
//        circleSingleLinkedList.showBoy();
        circleSingleLinkedList.countBoy(1,2,5);
    }
}

class CircleSingleLinkedList {
    private Boy first = null;

    public void addBoy(int nums) {
        if (nums < 1) {
            System.out.println("nums不正确");
            return;
        }
        Boy curBoy = null;
        for (int i = 1; i <= nums; i++) {
            Boy boy = new Boy(i);
            if (i == 1) {
                first = boy;
                first.setNext(first);
                curBoy = first;
            } else {
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }
    }

    public void showBoy() {
        if (first == null) {
            System.out.println("链表为空");
            return;
        }
        Boy curBoy = first;
        while (true) {
            System.out.printf("编号 %d \n", curBoy.getNo());
            if (curBoy.getNext() == first) {
                break;
            }
            curBoy = curBoy.getNext();
        }
    }

    //根据输入计算出圈顺序(不包括创建链表)
    public void countBoy(int startNo, int countNum, int nums) {
        if (first == null || startNo < 1 || startNo > nums) {
            System.out.println("输入错误");
            return;
        }
        Boy helper = first;
        while (true) {
            if (helper.getNext() == first) {
                break;
            }
            helper = helper.getNext();
        }
        for (int j = 0; j < startNo - 1; j++){
            first = first.getNext();
            helper = helper.getNext();
        }
        while (true){
            //圈中只有一人
            if (helper == first){
                break;
            }
            for(int j = 0; j<countNum-1;j++){
                first = first.getNext();
                helper = helper.getNext();
            }
            System.out.printf("编号 %d 出圈\n",first.getNo());
            first = first.getNext();
            helper.setNext(first);
        }
        System.out.printf("编号 %d 出圈",first.getNo());
    }
}

class Boy {
    private int no;
    private Boy next;

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

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Boy getNext() {
        return next;
    }

    public void setNext(Boy next) {
        this.next = next;
    }
}

原文地址:https://www.cnblogs.com/bingbug/p/12079422.html

时间: 2024-07-29 13:12:23

单向环形链表的相关文章

Java数据结构之单向环形链表(解决Josephu约瑟夫环问题)

1.Josephu(约瑟夫.约瑟夫环)问题: 设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列. 提示: 用一个不带头结点的循环链表来处理Josephu 问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法

07 - 单向环形链表应用场景 —— Josephu问题

1. Josephu 问题 设编号为1,2,- n的n个人围坐一圈,约定编号为 k(1<=k<=n)的人从1开始报数,数到 m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列 2. 解决思路 [简述]用一个不带头结点的循环链表来处理Josephu问题, 先构成一个有n个结点的单循环链表,然后由 k 结点 起从1开始计数,计到 m 时,对应结点从链表中删除,然后再从 被删除结点的下一个结点 又从1开始计数,直到最后一个结点从

实现约瑟夫环形链表

题目 41个人排成一个圆圈,由第1个人 开始报数,每报数到第3人,该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止.约瑟夫与朋友在第16与第31个位置,于是活了下来.请用单向环形链表描述该结构并呈现整个自杀过程. 设计 首先要设计一个节点模型 class Node { int value; Node next; Node(int value) { this.value = value; } } 遍历并用 last 节点做成一个单向线性的链表,之后将自身的初始节点指向last.ne

php实现单,双向链表,环形链表解决约瑟夫问题

传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn 聊天篇: 数学对我们编程来说,重不重要? 看你站在什么样的层次来说. 如果你应用程序开发,对数学要求不高 但是,如果你开发系统软件,比如(搜索/识别软件[图像,语言识别]/操作系统...)对数学高 建模.大量数学模型. 老师啊啊.我是学C++的.麻烦,谈哈对QT和MFC的看法嘛.前景什么的, 记住 : 打好基础,大有可为! 初中毕业能去传智学习吗? 学习It, 不管是java ,php ,c#,对

java 环形链表实现约瑟夫(Joseph)问题

约瑟夫问题又名丢手绢问题.相传著名犹太历史学家 Josephus 利用其规则躲过了一场自杀游戏,而后投降了罗马. 问题: 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.* 从编号为k的人开始报数,数到m的那个人出列:* 他的下一个人又从1开始报数,数到m的那个人又出列:* 依此规律重复下去,直到圆桌周围的人全部出列. 用节点来模拟游戏中的人,用链表来表示游戏中的人按一定的顺序排列.每一个节点给一个编号,从编号为k的节点开始计数,计到m的节点从链表中退出.之后m的下一个节点从新

双向链表和环形链表(约瑟夫问题)

双向链表 package linkedlist; public class DooubleLinkedListDemo { public static void main(String[] args) { HeroNode2 hero1 = new HeroNode2(1,"宋江","及时雨"); HeroNode2 hero2 = new HeroNode2(2,"卢俊义","玉麒麟"); HeroNode2 hero3 =

环形链表与约瑟夫环问题

思路: 代码: public class Josepfu { public static void main(String[] args) { // 测试一把看看构建环形链表,和遍历是否ok CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList(); circleSingleLinkedList.addBoy(125);// 加入5个小孩节点 circleSingleLinkedList.showBo

c语言:写一个函数建立一个有3名学生数据的单向动态链表

写一个函数建立一个有3名学生数据的单向动态链表. 解:程序: #include<stdio.h> #include<stdlib.h> #define LEN sizeof(struct Student) struct Student { long num; float score; struct Student *next; }; int n; struct Student *creat(void)//定义函数返回一个指向链表头的指针 { struct Student *head

环形链表---Java

/** * * @author Administrator * 功能:丢手帕问题 */ package com.litao; public class Demo4 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub CycLink cycLink = new CycLink(); cycLink.setLen(9); cycLink.createLin