목록 단방향 링을 설명합니다
- Josephu (요세푸스, 요세푸스) 문제
제공자 번째 N 개의 합의 번호 (k)의 주위에 앉아 1,2,3, N 개인 ...... (1 <= K <= N)의 선두 사람으로부터 패킷의 수, 열 번호 m을 그 사람 그것은시켜 팀의 일련 번호를 생성, 라인 업 중 모든 사람까지, 등등 점점 옆에 하나 개의 숫자에서 그 사람의 숫자 m에 밖으로 열, 및입니다.
- 신속한
n은 노드의 하나의 사이클을 구성하는 첫 번째 목록을 다음에서 그리스트로부터 제거 된 노드에 대응하는 상기 노드 (k)로부터 m 행 스톱워치를 카운팅을 시작하고, 엔드리스 체인 리드 노드 Josephu 문제를 다루는 노드 1은 삭제되고 시작 카운트에서 마지막 노드 목록 알고리즘 끝에서 삭제할 때까지.
- 도식 Josephu 문제
- 조셉 문제 - 원형 연결리스트의 그림을 만들 수있는 아이디어
단방향 원형 연결리스트 아이디어의 건설
1. 먼저, 첫 번째 노드를 만들도록 상기 제 노드 및 환형 포인트
2. 우리는 각각의 새 노드를 만들 백업 할 때, 노드를 기존 링 목록에 추가됩니다
원형 연결리스트 탐색
첫 번째 노드를 가리키는 포인터 보조 (가변) curBoy 허용 1.
2. 원형 연결리스트는 curBoy.next == 제 단부 while 루프를 통해 이송되고
-
조셉 문제 - 아이 아이디어 분석 차트를 LAPS
아이 링 시퀀스를 생성, 사용자 입력에 기초
N = 5, 즉, 다섯 개인
K = 1, 첫 번째 사람의 패킷의 수는 시작할
m = 2, 개수 2
보조 포인터 (변수) 도우미에 대한 수요를 만들기 1.이 지난 시점 이전 노드 목록을 울려합니다.
추가 : 아이의 수는 이전에보고 할 첫 번째 이동 및 도우미 K - 1 회
1 × - 다른 패킷 아이들의 수, m은 제 헬퍼 포인터 동시에 이동하게 2
3. 그런 다음 링의 첫 번째 자식 노드를 가리킬 수 있습니다
다음 내용을 선입 =
helper.next 먼저 =
原来first 指向的节点就没有任何引用,就会被回收
出圈的顺序 2->4->1->5->3
-
约瑟夫问题的代码实现
1 package com.jyj.linkedList; 2 3 public class Josephu { 4 public static void main(String[] args) { 5 CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList(); 6 circleSingleLinkedList.addBoy(5); 7 circleSingleLinkedList.showBoy(); 8 //测试小孩出圈顺序 9 circleSingleLinkedList.countBoy(1, 2, 5); 10 } 11 } 12 13 //创建一个环形的单向链表 14 class CircleSingleLinkedList { 15 //创建一个first节点,当前没有编号 16 private Boy first = new Boy(-1); 17 18 //添加小孩节点,构成环形链表 19 public void addBoy(int nums) { 20 //nums 做一个数据校验 21 if(nums < 1) { 22 System.out.println("nums 值不正确"); 23 return; 24 } 25 Boy curBoy = null; //辅助指针,帮助构建环形链表 26 //使用for来创建我们的环形链表 27 for(int i = 1;i <= nums;i++) { 28 //根据编号,创建小孩节点 29 Boy boy = new Boy(i); 30 //如果是第一个小孩 31 if(i == 1) { 32 first = boy; 33 first.setNext(first); 34 curBoy = first; 35 } else { 36 curBoy.setNext(boy); 37 boy.setNext(first); 38 curBoy = boy; 39 } 40 } 41 } 42 43 //遍历当前的单向环形链表 44 public void showBoy() { 45 //判空 46 if(first == null) { 47 System.out.println("链表为空,没有任何小孩~"); 48 return; 49 } 50 //因为first不能动,定义辅助指针 51 Boy curBoy = first; 52 while(true) { 53 System.out.printf("小孩的编号 %d\n", curBoy.getNo()); 54 if(curBoy.getNext() == first) { //遍历完毕 55 break; 56 } 57 curBoy = curBoy.getNext(); //curBoy后移 58 } 59 } 60 61 //根据用户输入,计算小孩出圈顺序 62 /** 63 * 64 * @param startNo 表示从第几个小孩开始数数 65 * @param countNo 表示数几下 66 * @param nums 表示最初有多少小孩在圈中 67 */ 68 public void countBoy(int startNo,int countNo,int nums) { 69 //数据校验 70 if(first == null || startNo < 1 || startNo > nums) { 71 System.out.println("参数不正,请重新输入"); 72 return; 73 } 74 //创建辅助指针(变量)helper,事先应该指向环形链表的最后这个节点。 75 Boy helper = first; 76 while(true) { 77 if(helper.getNext() == first) {//helper 是最后一个节点 78 break; 79 } 80 helper = helper.getNext(); 81 } 82 //小孩报数前,先让first 和 helper移动 startNo-1 次 83 for(int i = 0;i < startNo - 1;i++) { 84 first = first.getNext(); 85 helper = helper.getNext(); 86 } 87 while(true) { 88 if(first == helper) {//剩最后一个节点 89 break; 90 } 91 //小孩报数时,让first 和 helper指针同时的移动 countNo - 1 次 92 for(int i = 0;i < countNo - 1;i++) { 93 first = first.getNext(); 94 helper = helper.getNext(); 95 } 96 System.out.printf("小孩编号 %d 出圈\n", first.getNo()); 97 first = first.getNext(); 98 helper.setNext(first); 99 } 100 System.out.printf("最后一个小孩的编号是first : %d,helper : %d\n", first.getNo(),helper.getNo()); 101 } 102 } 103 104 //创建一个Boy类,表示一个节点 105 class Boy { 106 private int no;//编号 107 private Boy next;//指向下一个节点,默认为null 108 public Boy(int no) { 109 this.no = no; 110 } 111 public int getNo() { 112 return no; 113 } 114 public void setNo(int no) { 115 this.no = no; 116 } 117 public Boy getNext() { 118 return next; 119 } 120 public void setNext(Boy next) { 121 this.next = next; 122 } 123 }
以上