데이터 구조 및 알고리즘 분석 및 그래픽 실현의 조셉 문제

데이터 구조 및 알고리즘 분석 및 그래픽 실현의 조셉 문제


디렉토리

  1. josephu 문제
  2. josephu의 문제가 해결
  3. 코드 구현

1. josephu 문제

Josephu 문제 : 1,2 ... N 합의 번호 (k)에 앉아 각각의 설정 수 n 대 (L <= K <= N)의 사람들로부터 시작 패킷 카운트의 숫자
열 m의 사람 그것은하여, 라인업 중 모든 사람까지, 다음 한 수에서 그 사람의 숫자 m과 열에서 등 뻥
팀의 시퀀스 번호를 생성.

여기에 그림 삽입 설명

주 : 리드 노드 문제 Josephu 다루는 원형리스트 아니다하여 다음 번의 사이클 N 노드 목록 제 1 구성은 다음 오픈에서 노드 (k)에서 시작하여,
카운트 개시 시점부터 접속점에 대응하여 m 행의 개수, 마지막 목록에서 삭제 될 때까지 삭제 노드로 링크 된 목록을 제거하고 다음에서 하나 개의 노드에서 계산을 시작, 알고리즘은 종료


2. josephu의 문제가 해결

  1. 그래픽 아이디어의 원형 연결리스트 만들기
    여기에 그림 삽입 설명

  2. 아이의 생각은 분석 바퀴
    여기에 그림 삽입 설명


3. 코드 구현

package com.linkedList;

public class josepfu {
    public static void main(String[] args) {
        //测试一把看看构建环形链表,和遍历是否ok
        CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
        circleSingleLinkedList.addBoy(5);
        circleSingleLinkedList.showBoy();
        System.out.println();

        //测试一把小孩出圈是否正确
        circleSingleLinkedList.countBoy(1, 2, 5);
        
    }
}

//创建一个环形的单向链表
class CircleSingleLinkedList {
    //    创建一个first节点,当前没有编号
    private Boy first = null;

    //添加小孩节点,构建成一个环形链表
    public void addBoy(int nums) {
        //nums 做一个数据校验
        if (nums < 1) {
            System.out.println("nums的值不正确");
            return;
        }
        Boy curBoy = null; // 辅助指针,帮助构建环形链表
        //使用for循环来创建文明的环形链表
        for (int i = 1; i <= nums; i++) {
            //根据编号创建小孩节点
            Boy boy = new Boy(i);
            //如果是第一个小孩
            if (i == 1) {
                first = boy;
                first.setNext(first); //构成环
                curBoy = first; // 让curBoy指向第一个小孩
            } else {
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }
    }

    //遍历当前环形链表
    public void showBoy() {
        //判断链表是否为null
        if (first == null) {
            System.out.println("链表为null");
            return;
        }

        //因为first不能动,因此我们仍然使用一个辅助指针完成遍历
        Boy curBoy = first;
        while (true) {
            System.out.printf("小孩的编号%d\n", curBoy.getNo());
            if (curBoy.getNext() == first) {
                //说明已经遍历完毕
                break;
            }
            curBoy = curBoy.getNext();
        }
    }

    /**
     * 根据用户的输入,计算出小孩出圈的顺序
     *
     * @param startNo  表示从第几个开始数数
     * @param countNum 表示数几下
     * @param nums     表示最初由多少小孩在圈中
     */
    public void countBoy(int startNo, int countNum, int nums) {
        //先对数据进行校验
        if (first == null || startNo < 1 || startNo > nums) {
            System.out.println("参数输入有误,请重新输入");
            return;
        }
        //创建一个辅助指针,帮助小孩出圈
        Boy helper = first;
        //  需要创建一个辅助指针helper,实现应该指向环形链表的最后这个节点
        while (true) {
            if (helper.getNext() == first) {
                //说明helper指向最后小孩节点
                break;
            }
            helper = helper.getNext();
        }
        //小孩报数前,先让first和helper移动k-1次
        for (int j = 0; j < startNo - 1; j++) {
            first = first.getNext();
            helper = helper.getNext();
        }

        //当小孩报数时,让first和helper指针同时移动 m-1 次,然后出圈
        //这里是循环操作,直到圈中只有一个节点
        while (true) {
            if (helper == first) {
                //说明圈中只有一个节点
                break;
            }
            //让first和helper指针同时移动countNum -1,然后出圈
            for (int j = 0; j < countNum - 1; j++) {
                first = first.getNext();
                helper = helper.getNext();
            }
            //这时first指向的节点,就是要出圈的小孩节点
            System.out.printf("小孩%d出圈\n", first.getNo());
            //这是将first指向的小孩出圈
            first = first.getNext();
            helper.setNext(first);
        }
        System.out.printf("最后留在圈中的小孩编号%d\n", helper.getNo());
    }
}

// 创建一个Boy类,表示一个节点
class Boy {
    private int no; // 编号
    private Boy next; //指向下一个节点,默认null

    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;
    }
}

결과를 컴파일 :
여기에 그림 삽입 설명

추천

출처blog.csdn.net/weixin_41910694/article/details/92757067