单向环形链表及约瑟夫问题

问题介绍:
    *又称丢手帕问题
    *含编号的一组环形数组,从某一点开始遍历,每到第m个时数组元素出列
    *求出列序号的队列

单向环形链表:
    *最后一个元素节点指向第一个节点
    *构建思路
        1.创建第一个节点,使first指向该节点,并使其自身形成环形
        2.当我们每创建一个新节点,将其加入环形链表中
        3.添加过程
            *创建一个last指针等于尾节点
            *将last指针指向当前节点
            *当前节点指向first节点
            *last指针移动
    *解决问题思路
        1.创建一个辅助指针link,指向链表最后的节点
        2.当报数时,将link与first同时移动m - 1次
        3.这时将first指向节点输出
            *输出当前first
            *先将first后移
            *然后将link.next = first
    
    *代码总实现
      

 *package 单向环形链表;

        public class 约瑟夫问题 {

            public static void main(String[] args) {
                // TODO Auto-generated method stub
                
                CircleSingleLinkedList circleSingle = new CircleSingleLinkedList();
                circleSingle.addPeopleCircleList(5);
                circleSingle.List();
                circleSingle.Answer(2, 2, 5);
            }

        }

        //创建链表
        class CircleSingleLinkedList{
            
            //创建first节点,暂不赋值
            private PeopleCircleList first = null;
            
            //添加节点,构建环形链表
            public void addPeopleCircleList(int size){
                    //size数据检验
                    if(size < 1){
                        System.out.println("size error!");
                        return;
                    }
                    //创建last辅助节点
                    PeopleCircleList last = null;
                    for(int i = 1; i <= size; i++){
                        //根据编号创建节点
                        PeopleCircleList people = new PeopleCircleList(i);
                        if(i == 1){
                            first =people;
                            first.setNext(first);        //构成环形
                            last = first;    //辅助节点指向first
                        } else {
                            last.setNext(people);
                            people.setNext(first);
                            last = people; 
                        }
                    }
            }
            
            //遍历链表
            public void List(){
                
                //判断是否为空
                if(first == null){
                    System.out.println("没有数据");
                    return;
                }
                
                PeopleCircleList last = first;
                while(true){
                    System.out.printf("输出编号为:%d \n",last.getNum());
                    if(last.getNext() == first){
                        break;
                    }
                    last = last.getNext();
                }    
            }
            
            //解决问题
            public void Answer(int start,int size, int total){
                
                //数据校验
                if(first == null || start == 1 || start > total){
                    System.out.println("输入错误");
                }
                
                //创建临时节点
                PeopleCircleList link = first;
                while(true){
                    if(link.getNext() == first){
                        break;
                    }
                    link = link.getNext();
                }
                //移动至start
                for(int i = 0; i < start - 1; i++){
                    first = first.getNext();
                    link = link.getNext();
                }
                while(true){
                    if(link == first){
                        //只有一个元素剩余
                        break;
                    }
                    for(int j = 0; j < size - 1; j++){
                        first = first.getNext();
                        link = link.getNext();
                    }
                    System.out.printf("输出编号为:%d \n",first.getNum());
                    first = first.getNext();
                    link.setNext(first); 
                }
                System.out.printf("输出编号为:%d \n",first.getNum());
            }
        }

        //创建节点
        class PeopleCircleList{
            private int num;    //编号
            private PeopleCircleList next;        //指向下一个节点,默认为空
            
            public PeopleCircleList (int num){
                this.num = num;
            }

            public int getNum() {
                return num;
            }

            public void setNum(int num) {
                this.num = num;
            }

            public PeopleCircleList getNext() {
                return next;
            }

            public void setNext(PeopleCircleList next) {
                this.next = next;
            }
            
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值