数据结构- 环形链表以及约瑟夫问题

数据结构- 环形链表


前段时间跟着尚硅谷的视频学习,自己截图做了一些学习笔记,现在简单整理出来供大家参考,同时也方便自己日后复习查询,如果有存在疏漏,欢迎大家批评指正。文末将会附上视频链接。

单向环形链表

结构示意图

在这里插入图片描述

创建单向环形链表:

在这里插入图片描述

 //环形链表的构建
 public void addBoy(int nums){
         //nums做一个数据校验
         if (nums <1){
             System.out.println("nums的值不正确");
             return;
         }
         Boy curBoy=null;//辅助指针,帮助构建环形链表
         //使用for循环创建循环链表
         for (int i=1;i<=nums;i++){
             //根据编号,创建小孩节点
             Boy boy=new Boy(i);
             //如果是第一个小孩
             if (i==1){
                 first = boy;
                 first.setNext(first);//构成环
                 curBoy=first;//让curBoy指向第一个小孩
             }else {
                 curBoy.setNext(boy);
                 boy.setNext(first);
                 curBoy=boy;
             }
         }
     }

显示环形链表:
     //遍历环形链表
     public void showBoy(){
         //判断链表是否为空
         if(first==null){
             System.out.println("链表为空");
             return;
         }
         //用辅助指针完成遍历
         Boy curBoy=first;
         while (true){
             System.out.printf("小孩编号为%d \n",curBoy.getNo());
             if (curBoy.getNext()==first){//遍历完成
                 break;
             }
             curBoy=curBoy.getNext();//curBoy后移

         }
     }

约瑟夫问题

设编号为1,2,3…n的n个人围坐一圈,约定编号为k(1≤k≤n)的人从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的人又出列,依次类推,直到所有人出列为止,由此产生出一个出列编号的序列。

在这里插入图片描述

构建好环形链表后,进行出圈处理

在这里插入图片描述


   //根据用户的输入,计算出小孩出圈的顺序
   /*
    *      startNo -表示从第几个小孩开始数数
    *     countNum -表示数几下
    *    nums -表示最初有多少小孩在圈中
    */
   public void countBoy(int startNo, int countNum, int nums) {
       //先对数据进行校验
       if (first == null || startNo < 1 || startNo > nums) {
           System.out.println("参数输入有误,请重新输入");
           return;
       }
       //创建辅助接点,帮助小孩出圈
       Boy helper = first;
       //创建辅助指针helper,事先应该指向环形链表的最后节点
       while (true){
           if (helper.getNext()==first){
               break;
           }
           helper=helper.getNext();
       }
       //小孩报数前,先让first和helper 移动k-1次
       for (int j=0;j<startNo-1;j++){
           first=first.getNext();
           helper=helper.getNext();
       }
       //当小孩报数时,让first和helper指针同时移动m-1次,然后出圈
       //这是一个循环操作,直到圈中只有一个节点
       while (true){
           if (helper==first){//说明圈中只有一个节点
               break;
           }
           //让first和helper指针同时移动m-1次,
           for (int j=0;j<countNum-1;j++){
               first=first.getNext();
               helper=helper.getNext();
           }
           //这时first指向的节点,就是要出圈的节点
           System.out.printf("小孩%d出圈\n",first.getNo());
           //first节点出圈
           first=first.getNext();
           helper.setNext(first);
       }
       System.out.printf("最后留着圈中的小孩%d\n",first.getNo());
   }

在此附上尚硅谷的教学视频:
【尚硅谷】数据结构与算法(Java数据结构与算法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值