• 约瑟夫环问题1求解


    约瑟夫环问题:
    * 背景:约瑟夫叙述了他和40个士兵在罗马战争期间被罗马军队包围之后签订的一人自杀协定。
    * 约瑟夫建议每个人杀掉他旁边的人,约瑟夫利用制定的规则使自己成为这些人中唯一的幸存者。
    * 编程:

       1.考虑存储结构:顺序存储结构和链式存储结构(杀人模拟删除节点,链表更适合)
       2.场景:程序需要处理8个士兵组成的线性表,因为每个人要杀掉他的邻居,则要保证
       每个人都有邻居,因此采用循环单链表操作,指针指向的位置表示邻居。
       3.核心思想:从循环单链表中某个节点开始依次去除其相邻节点,直到链表中剩下一个节点为止

     ##思考使用循环双链表及奇数的情况

    1.循环单链表数据结构

      1 package com.neusoft.link;
      2 import com.neusoft.List.IList;
      3 /**
      4  * @author zhao-chj
      5  * 循环单链表
      6  */
      7 public class CircleLinkList implements IList{
      8     public Node head;
      9     public CircleLinkList() {
     10         // TODO 初始化
     11         head=new Node();//初始化头结点
     12         head.next=head;
     13     }
     14     @Override
     15     public void clear() {
     16         // TODO 清空
     17         head.next=head;
     18     }
     19     @Override
     20     public boolean isEmpty() {
     21         // TODO 判空
     22         return head.next.equals(head);
     23     }
     24     @Override
     25     public int length() {
     26         // TODO 长度
     27         Node p =head.next;
     28         int length=0;
     29         while (!p.equals(head)) {
     30             p=p.next;
     31             length++;
     32         }
     33         return length;
     34     }
     35     @Override
     36     public Object get(int i) {
     37         // TODO 读取带头结点的循环链表中第i个数据元素
     38         Node p=head.next;
     39         int j=0;
     40         while (!p.equals(head)&&j<i) {
     41             p=p.next;
     42             j++;
     43         }
     44         if (j>i||p.equals(head)) {
     45             System.out.println("第"+i+"个元素不存在!");
     46         }
     47         return p.data;
     48     }
     49 
     50     @Override
     51     public void insert(int i, Object x) {
     52         // TODO 带头结点的循环链表中第i个节点之前插入一个值为x的元素
     53         Node p = head;
     54         int j=-1;//第i个节点前驱位置
     55         while ((!p.equals(head)||j==-1)&&j<i-1) {
     56             p=p.next;
     57             j++;
     58         }
     59         if (j>i-1||(p.equals(head)&&j!=-1)) {
     60             System.out.println("插入位置不合法!");
     61         }
     62         Node s =new Node(x);
     63         s.next=p.next;
     64         p.next=s;
     65     }
     66 
     67     @Override
     68     public void remove(int i) {
     69         // TODO 移除循环单链表中第i个元素的节点,注意i的范围
     70         Node p=head;//p指向要删除节点的前驱节点
     71         int j=-1;
     72         while ((!p.next.equals(head)||j==-1)&&j<i-1) {//找前驱元素
     73             p=p.next;
     74             j++;
     75         }
     76         if (j>i-1||(p.next.equals(head)&&j!=-1)) {
     77             System.out.println("删除位置不合法!");
     78         }
     79         p.next=p.next.next;
     80     }
     81 
     82     @Override
     83     public int indexOf(Object x) {
     84         // TODO 查找值为x的元素,返回位置
     85         Node p =head.next;//p指向首节点
     86         int j=0;
     87         while ((!p.equals(head))&&(!p.data.equals(x))) {
     88             p=p.next;
     89             j++;
     90         }
     91         if (!p.equals(head)) {
     92             return j;
     93         }else {
     94             return -1;
     95         }
     96     }
     97     @Override
     98     public void display() {
     99         // TODO 输出元素
    100         Node p =head.next;
    101         while (!p.equals(head)) {
    102             System.out.print(p.data+" ");
    103             p=p.next;
    104         }
    105         System.out.println();
    106     }
    107 
    108     @Override
    109     public int remove(Object i) {
    110         // TODO Auto-generated method stub
    111         return 0;
    112     }
    113 
    114 }
    点击+展开代码

    2.约瑟夫环循环单链表求解

     1 package com.neusoft.exercise;
     2 
     3 import java.util.Scanner;
     4 
     5 import com.neusoft.link.CircleLinkList;
     6 
     7 /**
     8  * @author zhao-chj
     9  * 约瑟夫环问题:
    10  * 来源:约瑟夫叙述了他和40个士兵在罗马战争期间被罗马军队包围之后签订的一人自杀协定。
    11  * 约瑟夫建议每个人杀掉他旁边的人,约瑟夫利用制定的规则使自己成为这些人中唯一的幸存者。
    12  * 编程:1.考虑存储结构:顺序存储结构和链式存储结构(杀人模拟删除节点,链表更适合)
    13  *     2.场景:程序需要处理8个士兵组成的线性表,因为每个人要杀掉他的邻居,则要保证
    14  *     每个人都有邻居,因此采用循环单链表操作,指针指向的位置表示邻居。
    15  *     ##可以考虑使用循环双链表
    16  *     3.核心思想:从循环单链表中某个节点开始依次去除其相邻节点,直到链表中剩下一个节点为止
    17  *     
    18  */
    19 public class TestLinearTable06 {
    20     public static void main(String[] args) {
    21         CircleLinkList circleLinkList = new CircleLinkList();
    22         Scanner sc = new Scanner(System.in);
    23         System.out.println("请您输入士兵的个数~");
    24         int num = sc.nextInt();
    25         System.out.println(num+"士兵分别为:");
    26         for (int i = 0; i < num; i++) {
    27             //输入num个士兵
    28             circleLinkList.insert(i, sc.next());
    29         }
    30         for (int i = 0; circleLinkList.length()>1; ) {
    31             i = i%circleLinkList.length();
    32             System.out.println("长度:"+circleLinkList.length());//测试用可注释
    33             //读取到链表中位序号为i的士兵
    34             String str1= circleLinkList.get(i).toString();
    35             System.out.println("STR1:"+str1);//测试用可注释
    36             //求出相邻士兵在链表中的位序号
    37             i=++i%circleLinkList.length();
    38             //相邻的士兵
    39             String str2 =circleLinkList.get(i).toString();
    40             System.out.println("STR2:"+str2);//测试用可注释
    41             //杀死相邻的士兵
    42             circleLinkList.remove(i);
    43             //输出谁杀死谁的信息
    44             System.out.println(str1+"杀死"+str2);
    45         }
    46         System.out.println("活着的是(约瑟夫)是:"+circleLinkList.get(0));
    47     }
    48 }

    3.结果测试

    •     1.加入一些输出语句的测试

        

    •     2.不带输出语句的测试

       

  • 相关阅读:
    树莓派安装parrot linux记录
    Arch linux(UEFI+GPT)安装及后续优化教程
    VS部分安全函数用法
    C语言博客作业06--结构体&文件
    C语言博客作业05--指针
    C语言博客作业04--数组
    C语言博客作业03--函数
    C语言博客作业02--循环结构
    DS博客作业08--课程总结
    DS博客作业07--查找
  • 原文地址:https://www.cnblogs.com/jackchen-Net/p/6599319.html
Copyright © 2020-2023  润新知