环形链表操作及约瑟夫问题
单向环形链表: 约瑟夫问题:假设有n个人围成一圈,约定编号为k的人从1开始数数,数到m的那个人出列,他的下一个又从1开始数数, 数到m的人也出列,直到所有人都出列为止,由此产生一个出队编号的序列。 例如: n = 5 5个人 k = 1 从第一个开始 m = 2 数到2就出列 1、2、3、4、5 1、2 出队列的编号为:2 剩余队列1、3、4、5并从3开始报1 3、4 出队列的编号为:4剩余队列1、3、5 5、1 出队列的编号为1 剩余队列3、5并从3开始报1 3、5 出队列的编号为5 剩余队列3,最后只有3出队列 因此出队列顺序为2、4、1、5、3
环形链表的实现思路: 1、创建一个实体类Boy,对应属性no编号、next下一个节点 2、先创建一个first节点编号随便给,后期第一个真正加入的节点编号覆盖它 3、当只有一个真正的节点时就自己和自己环形first = boy(1);first.setnext(first); 4、使用一个临时变量节点记录当前环形链表加入到最后的节点是什么,下次有节点接入时就在这个节点后面 5、temp = boy(1);下一个接入时就temp.setnext(boy(2));boy(2).setnext(first);temp=boy(2);这样就加入了
约瑟夫问,根据输入个数生成一个小孩出圈顺序 思路: 1、创建一个辅助节点temp指向链表的最后一个节点,让小孩报数前将first和temp移动到报数小孩的节点和后一个节点 2、当小孩报数时,让first和temp同时移动,移动m-1次 3、这时就将first指向的节点出圈 4、出圈处理,先让first往前移动一次,然后temp的下一个节点指向移动后的first 下面是实现代码:
package com.ringList;
public class RingListDemo {
public static void main(String[] args) {
RingList ringList = new RingList();
ringList.addByNum(5);
ringList.josephu(1,2,5);
}
}
class RingList{
private Boy first = new Boy(-1);
Boy temp = null;
void addByNum(int num){
if (num<1){
System.out.println("输入的数字不对");
return;
}
if (first.getNext()==null){
Boy boy = new Boy(1);
first = boy;
first.setNext(first);
temp = boy;
}
for (int i = 2;i<=num;i++){
Boy boy = new Boy(i);
temp.setNext(boy);
boy.setNext(first);
temp = boy;
}
System.out.println("创建结束");
}
void addByBoy(Boy boy){
if (first.getNext()==null){
first = boy;
first.setNext(first);
temp = boy;
}else {
temp.setNext(boy);
boy.setNext(first);
temp = boy;
}
}
void show(){
if (first.getNext()==null){
System.out.println("链表数据为空");
return;
}
Boy temp = first;
while (temp.getNext()!=null){
System.out.println(temp);
if (temp.getNext().equals(first)){
break;
}
temp = temp.getNext();
}
}
void josephu(int startNo,int count,int num){
if (first==null||startNo<1||num<startNo){
System.out.println("输入的参数有误,请重新输入");
return;
}
Boy temp = first;
while (true){
if (temp.getNext().equals(first)){
break;
}
temp = temp.getNext();
}
for (int i=0;i<startNo-1;i++){
temp = temp.getNext();
first = first.getNext();
}
while (true){
if (temp.equals(first)){
break;
}
for (int j=0;j<count-1;j++){
temp = temp.getNext();
first = first.getNext();
}
System.out.println(first);
first = first.getNext();
temp.setNext(first);
}
System.out.println("最后留在圈中的小孩是"+temp);
}
}
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;
}
@Override
public String toString() {
return "Boy{" +
"no='" + no + '\'' +
'}';
}
}
以上代码是在跟着韩老师学习时,顺着韩老师提供的思路自己实现的,请大家多多指教!!!
|