java 单向环形链表 解决约瑟夫的问题

什么是约瑟夫问题

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k(1<=k<=n)的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

首先定义一个结点

public class Node {
	//编号
    int no;
    String name;
    //下一个结点
    Node next;

    public Node() {
    }

    public Node(int no, String name) {
        this.no = no;
        this.name = name;

    }
    public Node(int no) {
        this.no = no;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

接下来定义单向环形链表的主要功能

	public class CirLinkedList {

    private Node head;
    CirLinkedList(){
        Node node = new Node();
        node.no=-1;
        node.name="";
        //环形链表
        head=node;
        node.next=head;
    }

    void insert(Node node){
            //遍历至链表的结尾
            Node temp=head;
            while(temp.next!=head){
                temp=temp.next;
            }
        node.next=temp.next;
        temp.next=node;
    }

    void  delete(int no){
        //遍历至链表的结尾
        Node temp=head;
        while(temp.next!=head){
            //条件满足说明就有数据
            if(temp.next.no==no){
                System.out.println(temp.next);
                temp.next=temp.next.next;
                break;
            }
            temp=temp.next;

        }
    }


    void soleJosephu(int k,int m){
        //有数据才遍历
        if(head.next!=head){
            //如果头结点的next指向自己说明没有数据了
            int count=0;
            boolean flat=true;
            Node temp=head;
            while(head.next!=head){
                temp=temp.next;
                if(temp==head){
                    continue;
                }
                else{

                    if(count==m&&!flat)
                        count=0;
                    count++;
                }
                if(count==k&&flat){
                    count=1;
                    flat=false;
                }
                if(count==m&&!flat){
                    int delNo=temp.no;
                    //删除之前要移动指针
                    //temp=temp.next;
                    //count=1;
                    delete(delNo);
                }


            }
        }
    }
}

让我们看下测试类

 CirLinkedList list = new CirLinkedList();
        for (int i = 1; i < 10; i++) {

            Node n = new Node(i);
            list.insert(n);
        }
        int k=1;
        int m= 4;
        list.soleJosephu(k,m);

看下测试数据的结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值