zoukankan      html  css  js  c++  java
  • 约瑟夫问题

    约瑟夫问题

    1. 设编号1,2........n的那个人围坐一圈,约定编号k(1<=k<=n)的人从开始报数,数到m的那个出列,从它的下一位又开始从1开始报数,数到m的那个人又出列,以此类推,直到剩下一个人;

      解决方法: 使用一个不带头节点的循环链表来处理,先构成一个有n个结点的循环链表,然后从k结点起1开始计数,记到m时,对应结点从链表中删除,然后再从被删除的结点的下一个结点又开始从1计数,直到剩下一个结点为止;

    2. 代码实现

      1)创建单链表

      ​ 先创建第一个结点,让first指向第一个结点,并形成环:first.next = first

      ​ 后面每创建一个结点,就加入到已有的环中;

      2)出圈的方法解析:

      ​ ① 需要创建一个辅助指针helper,让它总是指向最后一个结点的位置;

      ​ ② 假设起始位置为startNum, 那么helper指针和first都要移动startNum-1次;

      ​ ③ 然后小孩开始报数,假如报数m下,那么helper和first都要移动m-1次,移动后first位置的孩子为要出圈的孩子,则:first = first.next (first后移); helper.next = first;

      ​ ④ 直到first == helper的时候剩下一个结点;

      public class JosepfuList {
          public static void main(String[] args) {
              forList forList = new forList();
              forList.setFroArr(5);
           //   forList.getList();
             forList.countBoy(1,2,5);
          }
      }
      class forList {
          private Node first = null;
      
          //创建环形链表
          public void setFroArr(int nums) {
              if (nums<1) {
                  System.out.println("输入正确的数量");
                  return;
              }
              Node curr = null;  //辅助结点
              for (int i =1; i<=nums; i++) {
                  // 创建结点
                  Node body = new Node(i);
                  if (i==1) {
                     first = body; //将该节点设置为first结点
                     curr = first;
                    curr.next = first;
                  } else {
                      curr.next = body;
                      body.next = first;
                      curr = body;
                  }
              }
          }
      
          // 根据用户输入,计算出小孩出小孩顺序
      
          /**
           *
           * @param startNo 从第几个开始
           * @param countNum 数几个数
           * @param nums 孩子总数
           */
          public void countBoy(int startNo, int countNum, int nums){
               if (startNo < 1 || countNum > nums || first==null) {
                   System.out.println("请输入正确数据");
                   return;
               }
               Node helper = first; // 辅助指针,让其指向最后一个结点
              while (true) {
                  if (helper.next == first) {
                      break;
                  }
                  helper =helper.next;
              }
              /**
               * 在报数前让first和helper移动到startNo-1次
               */
             for (int i=0;i<startNo-1;i++) {
                 helper = helper.next;
                 first = first.next;
             }
             // 小孩开始报数,让first和helper指针同时移动countNum-1次,然后出圈,直到圈中只有一个结点
      
              while (true) {
                  if (first == helper) {
                     break;
                  }
                 //让first和helper指针同时移动countNum-1次,first指向要出圈的结点
                 for (int j=0; j<countNum-1; j++) {
                     first = first.next;
                     helper = helper.next;
                 }
                  System.out.println(first.no);
                 first = first.next;
                 helper.next = first;
              }
              System.out.println(first.no);
          }
      
          // 遍历环形链表
          public void getList() {
              if (first == null) {
                  System.out.println("链表为null");
                  return;
              }
              Node curr = first;
              while (true) {
                  if (curr.next == first) {
                      System.out.println(curr.no);
                     return;
                  }
                  System.out.println(curr.no);
                  curr = curr.next;
              }
          }
      }
      // 创建一个结点
      class Node {
          public int no;
          public Node next;
      
          public Node(int no) {
              this.no = no;
          }
      
          @Override
          public String toString() {
              return "Node{" +
                      "no=" + no +
                      '}';
          }
      }
      

  • 相关阅读:
    找回感觉的练习
    第四次博客作业-结对项目
    zookeeper启动脚本
    docker自己制作centos7-jdk1.8-tomcat8
    Docker运行springboot的项目
    从list中模糊查询字符串
    Java实现文件下载
    hadoop的HA集群搭建
    oauth2 feign 报401的错误
    SpringBoot mybatis 自定义分页插件 注解版
  • 原文地址:https://www.cnblogs.com/cqyp/p/14654145.html
Copyright © 2011-2022 走看看