zoukankan      html  css  js  c++  java
  • 环形链表

    一.简介:

    环形链表也叫循环链表(可以是双链表、也可以是单链表),操作原理和单链表差不多,只是最后一个节点不在指向空(null)而是头(head),这里以单链表举例:

    二.代码实现约瑟夫问题

    1)构建一个单向的环形链表思路

    • 先创建第一个节点,让first指向该节点,并形成环形
    • 后面当我们每创建一个新的节点,就把该节点加入到已有的环形链表中即可。

    2)遍历环形链表

    • 先让一个辅助指针(变量)curBoy,指向first节点
    • 然后通过一个while循环遍历该环形链表即可,curBoy.next == first结束

    5. 约瑟夫问题小孩出圈的思路分析

    1.定义孩子类型
    public class Boy {
        private  int no;//编号
        private  Boy next;//指向下一个节点
    
        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;
        }
    
        public Boy(int no) {
            this.no = no;
        }
    }

      

    2.定义循环链表
    public class CircleSingleLinkedList {
        private Boy first = new Boy(-1);
        //添加小孩节点,构建一个环形链表
        public  void addBoy(int nums){
            //参数校验
            if (nums<1){
                System.out.println("nums的值不正确");
                return;
            }
            Boy curBoy = null;//辅助指针
            for (int i = 1; i <= nums; i++) {//使用for循环创建环形链表
                //根据编号创建小孩节点
                Boy boy = new Boy(i);
                //如果是第一个小孩
                if (i==1){
                    first=boy;
                    first.setNext(first);//构成一个换
                    curBoy=first;//将指针指向第一个节点
                }else {
                    curBoy.setNext(boy);
                    boy.setNext(first);
                    curBoy=boy;//指针后移
                }
            }
        }
    
    
        /*遍历环形链表*/
        public  void  showBoy(){
           /*判断链表是否为空*/
            if (first.getNext()==null){
                System.out.println("环形链表为空!!!");
                return;
            }
            Boy curBoy = first;
            while (true){
                System.out.printf("小孩的编号:%d
    ",curBoy.getNo());
               if (curBoy.getNext()==first){//遍历完毕
                   break;
               }
               curBoy=curBoy.getNext();//指针后移
            }
    
        }
    
    
        /*根据用户的输入计算出小孩出圈的顺序*/
    /**
     *
     * @description:TODO
     * @params:1.第几个小孩开始2.表示数几下,3.最初有多少个小孩
     * @return:
     * @author: sxw
     * @time: 2020/3/11 20:32
     */
        public void countBoy(int startNo,int countNum,int nums){
            //参数校验
            if (first == null||startNo<0||startNo>nums){
                System.out.println("输入参数有误,请重新输入");
                return;
            }
            Boy helper = first;
            while (true){//将指针指向最后一个节点
                if (helper.getNext()==first){
                    break;
                }
                helper=helper.getNext();
            }
            //小孩报数,将first和helper移动K-1次
            for (int i = 0; i <startNo-1 ; i++) {
                first=first.getNext();
                helper=helper.getNext();
            }
            //报数时将first和helper同时移动m-1次,然后出圈
            //当圈内只有一个节点时循环结束
            while (true){
                if (helper==first){//什么时候结束圈内只有一个节点
                    break;
                }
                //让first和helper同时移动countNum次
                for (int i = 0; i <countNum-1 ; i++) {
                    first=first.getNext();
                    helper=helper.getNext();
                }
                //这时first指向的是小孩出圈的节点
                System.out.printf("小孩%d出圈
    ",first.getNo());
                //first指向的小孩出圈
                first=first.getNext();
                helper.setNext(first);
            }
            System.out.printf("最后留着圈中小孩编号%d
    ",first.getNo());
    
        }
    
    }
    

     3.进行测试 

    public class JosepFu {
        public static void main(String[] args) {
            //测试构建和遍历环形链表是否ok
            CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
            circleSingleLinkedList.addBoy(5);
            circleSingleLinkedList.showBoy();
            /*测试小孩出圈*/
            circleSingleLinkedList.countBoy(1,2,5);
    
        }
    }
    

      

  • 相关阅读:
    Day 03
    Day 03 作业
    Day 02 作业
    Day 02
    Day 01
    Day 10 面向对象基础
    Spring学习-- Bean 的作用域
    一、基本知识
    cloud-init使用技巧
    如何在KVM中管理存储池
  • 原文地址:https://www.cnblogs.com/sxw123/p/12747871.html
Copyright © 2011-2022 走看看