package com.structure.linkedList;
import java.util.LinkedList;
/**
* 单向环形链表-约瑟夫问题
*/
public class CircleSingleLinkedListDemo {
public static void main(String[] args) {
CircleSingleLinkedList list = new CircleSingleLinkedList();
list.add(5);
list.showLinkedList();
list.countPerson2(2,5);
System.out.println(list.countPerson3(2,5));
}
}
class CircleSingleLinkedList{
CircleSingleNode firstNode = null;
//添加节点,构建单向环形链表
public void add(int num){
if(num<1){
System.out.println("参数有误");
return;
}
//定义一个辅助遍量
CircleSingleNode curNode = null;
for (int i=1;i<=num;i++){
CircleSingleNode node = new CircleSingleNode(i);
//判断是否为第一个节点
if(i==1){
firstNode=node; //将第一个节点指向当前节点
firstNode.setNext(firstNode);
curNode=firstNode;
}else {
curNode.setNext(node);
node.setNext(firstNode);
curNode=node;
}
}
}
//遍历单向环形链表
public void showLinkedList(){
//定义一个辅助指针指向firstNode节点
CircleSingleNode curNode = firstNode;
while (true){
System.out.println("当前节点的编号是:"+curNode.getNo());
if(curNode.getNext()==firstNode){//如果当前指针的下一个节点是第一个节点则表示循环完成
break;
}
curNode = curNode.getNext();
}
}
//约瑟夫问题:有n个人,每次从第k个人开始数数,数到第m个数的人就自杀
//自定义链表实现
public void countPerson(int k,int m,int n){
//先进行数据校验
if(n<1 || k<1||m<0||k>n){
System.out.println("参数不合理");
return;
}
//定义一个辅助变量指向环形链表第一个节点的前一个节点
CircleSingleNode helperNode = firstNode;
//循环遍历找到helperNode的位置
while (true){
if(helperNode.getNext()==firstNode){
break;
}
helperNode = helperNode.getNext();
}
//循环遍历找到第k个人开始数数时first和helper的位置
for(int i=1;i<=k-1;i++){
firstNode=firstNode.getNext();
helperNode=helperNode.getNext();
}
//
while (true){
if(helperNode==firstNode){
break;
}
//first和helper移动m-1次
for(int i=1;i<=m-1;i++){
firstNode=firstNode.getNext();
helperNode=helperNode.getNext();
}
//此时firstNode就是要自杀的人的位置
System.out.println("要自杀的人的编号是:"+firstNode.getNo());
//将找到的位置的人移除链表
firstNode=firstNode.getNext();
helperNode.setNext(firstNode);
}
System.out.println("最后活下来的人的编号是:"+firstNode.getNo());
}
/**
* 使用LinkedList实现
* @param m m是数的数
* @param n n表示一共有多少个人
*/
public void countPerson2(int m,int n){
LinkedList<Integer> linkedList = new LinkedList<Integer>();
for (int i=1;i<=n;i++){
linkedList.add(i);
}
int removeIndex = 0;
while (linkedList.size()!=1){
removeIndex = (removeIndex+m-1)%linkedList.size();
System.out.println("当前编号是:"+linkedList.get(removeIndex));
linkedList.remove(removeIndex);
}
System.out.println("最后活下来的人的编号是:"+linkedList.get(0));
}
//使用递归的方式得到最后一个活下来的人的编号
public int countPerson3(int m,int n){
if(n==1){
return 0;
}
return ((countPerson3(m,n-1)+m)%n)+1;
}
}
class CircleSingleNode{
private int no;
private CircleSingleNode next;
public CircleSingleNode(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public CircleSingleNode getNext() {
return next;
}
public void setNext(CircleSingleNode next) {
this.next = next;
}
}
约瑟夫问题-单向环形链表的简单代码实现
最新推荐文章于 2021-09-14 08:38:30 发布