约塞夫环问题

1.定义

给出正整数n,表示一个从1~n的环,再给出一个报数m,开始从1开始报数,报到m时,从环中去掉这个数,下个位置继续从1开始报数,直到整个环没有数字为止,依次输出这些数。

2.思路

解决这种环形问题,我们首先想到的是循环结构体,这里采用循环单链表来解决,记录前驱节点和当前节点位置,当当前节点p的报数等于m时,利用前驱节点删除它,用一个count计数,当删除的数为n时,让当前节点为空,则退出了循环。

这里给出一个n为8的环。

3.代码实现:

import java.util.Scanner;

//定义节点信息
class Node{
     int data;
     Node next;
     public Node(int data){ this.data=data;}
}
class Solution{
    //用单循环链表来创建约塞夫环
    public void CreateLink(int n,Node h,Node r){
        for (int i = 1; i <=n ; i++) {
            Node p=new Node(i);
            r.next=p;
            r=r.next;
        }
        r.next=h.next;
    }
    //约塞夫环解决方法
    public int[] way(int n,int m,Node h,Node r){
        Node p=h.next,pre=r;   //p为当前节点,pre为前驱节点
        int k=0,count=0;   //k为当前节点报数,count为删除节点数
        int res[]=new int[n];  //用数组来保存结果
        while (p!=null){   
            k++;    //当前报数
            if (k==m){   //等于最大报数时,删除节点
                res[count++]=p.data;
                if (count==n){   //退出循环操作
                    p=null;
                    continue;
                }
                pre.next=p.next;  //删除节点
                p=p.next;
                k=0;    //下个节点从新开始计数
            }
            else {  //不符合条件,后移
             p=p.next;   
             pre=pre.next;
            }
        }
        return res;
    }
}
public class Joseph_circle {
    public static void main(String args[]){
        Solution solution=new Solution();
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();  //节点个数
        int m=sc.nextInt();  //报数最大值
        Node h=new Node(0);  //带头结点的链表
        Node r=h;
        solution.CreateLink(n,h,r);
        int res[]=solution.way(n,m,h,r);
        for (int k:res) {
            System.out.println(k);
        }
    }
}

4.实验结果

输入n=8,m=3的结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值