最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java數(shù)據(jù)結(jié)構(gòu)之環(huán)形鏈表和約瑟夫問題詳解

 更新時(shí)間:2022年08月15日 11:23:19   作者:小黎的培培筆錄  
約瑟夫(Josephus)問題是單向環(huán)形鏈表的一種體現(xiàn),也就是丟手帕問題,下面這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)結(jié)構(gòu)之環(huán)形鏈表和約瑟夫問題的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、環(huán)形鏈表

1、創(chuàng)建結(jié)點(diǎn)

環(huán)形鏈表其實(shí)也很好理解,就是將單鏈表的頭和尾連接起來,就形成了環(huán)形鏈表。

public class Node {
    public int data;
    public Node next;
 
    public Node(int data) {
        this.data = data;
    }
 
    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                '}';
    }
}

2、添加小結(jié)點(diǎn)

寫一個(gè)方法用來添加結(jié)點(diǎn),這個(gè)方法我們直接傳入需要?jiǎng)?chuàng)建結(jié)點(diǎn)的個(gè)數(shù),然后再方法中直接創(chuàng)建出一個(gè)簡(jiǎn)單的循環(huán)鏈表。代碼解析:

//創(chuàng)建一個(gè)first結(jié)點(diǎn),當(dāng)前沒有編號(hào)
public Node first = new Node(-1);
   
     public void add(int n){
        //其實(shí)循環(huán)鏈表,一個(gè)結(jié)點(diǎn)也可以循環(huán),但這里為了方便后面介紹約瑟夫問題
        //我們循環(huán)的結(jié)點(diǎn)不能少于兩個(gè)所以做了這個(gè)判斷。
        if (n < 2){
            System.out.println("n的值不正確");
            return;
        }
 
        //輔助結(jié)點(diǎn)
        Node end = null;
 
        //使用for循環(huán)來創(chuàng)建鏈表
        for (int i = 1; i <= n; i++) {
 
            //根據(jù)編號(hào)創(chuàng)建結(jié)點(diǎn)
            Node node = new Node(i);
 
            //如果是第一個(gè)結(jié)點(diǎn),first頭指向第一個(gè)結(jié)點(diǎn),end表示尾,回過頭來指向first,形成循環(huán)
            if(i == 1){
                first = node;
                end = first;
            }else{
                //先將尾部end的next指向新的結(jié)點(diǎn)node,然后end后移指向新的結(jié)點(diǎn),
                //再將end的next指向第一個(gè)結(jié)點(diǎn)first,這樣就形成了循環(huán)
                end.next = node;
                end = end.next;
                end.next = first;
            }
 
        }
    }

3、顯示循環(huán)鏈表

顯示循環(huán)鏈表的方式和單鏈表的顯示方式差不多,關(guān)鍵點(diǎn)在于如何判斷循環(huán)鏈表的結(jié)束,我們的尾部是指向頭部的,所以當(dāng)尾部的next指向的結(jié)點(diǎn)等于頭部,就是最后一個(gè)結(jié)點(diǎn),此時(shí)就退出循環(huán)。

  public void show(Node first){
 
        //判斷循環(huán)鏈表是否為空
        if (first.next == first){
            System.out.println("列表為空!");
            return;
        }
        
        //輔助結(jié)點(diǎn)
        Node temp = first;
        //循環(huán)打印
        while (true){
 
            System.out.println(temp);
            //最后一個(gè)結(jié)點(diǎn)的next等于first,就退出
 
            if (temp.next == first){
                break;
            }
 
            temp = temp.next;
        }
    }

二、約瑟夫問題  

1、問題描述

約瑟夫(Joseph)問題的一種描述是:編號(hào)為1,2,...n的n個(gè)人按順時(shí)針方向圍坐一圈,每人持有一個(gè)密碼(正整數(shù))。開始選任一個(gè)正整數(shù)作為報(bào)數(shù)上限值m, 從第一個(gè)人開始按順時(shí)針方向自1開始順序報(bào)數(shù), 報(bào)到m時(shí)停止報(bào)數(shù)。 報(bào)m的人出列, 將它的密碼作為新的m值。 試設(shè)計(jì)一個(gè)程序求出出列順序。

2、首先確定圈大小及開始位置

? 寫一個(gè)方法

        start :表示從哪一個(gè)位置開始

        m : 報(bào)多少個(gè)數(shù),報(bào)到m個(gè)數(shù)的人出列

        n :圈總的大小

public void goOutCircle(int start,int m, int n){
}

? 確定圈的大小

        傳入的n要多余兩個(gè)人才能玩,然后傳入的開始位置start不能在總?cè)藬?shù)之外,符合條件,我們調(diào)用前面我們介紹的方法add()進(jìn)行循環(huán)鏈表的創(chuàng)建。

        if (n >= 2 && start <= n){
            add(n);
        }else {
            System.out.println("輸入異常!");
            return;
        }

? 確定開始位置

        first是指向鏈表的第一個(gè)的,但我們開始的位置可以是任何一個(gè)結(jié)點(diǎn),所以先聲明輔助結(jié)點(diǎn)temp,遍歷循環(huán)鏈表,如果結(jié)點(diǎn)的data和傳入的start的值相等,就找到了開始位置,將first 指向開始位置temp,然后循環(huán)就結(jié)束了。

        Node temp = first;
        while (true){
            if (temp.data == start){
                first = temp;
                break;
            }
            temp = temp.next;
        }

3、出圈操作

首先,我們需要一個(gè)輔助的結(jié)點(diǎn)end,然后假設(shè)開始位置在數(shù)據(jù)2的地方,first和end都指向數(shù)據(jù)2,數(shù)的次數(shù)為m = 2。

開始數(shù)數(shù),數(shù)據(jù)3的位置是數(shù)數(shù)m = 2 的時(shí)候,這時(shí)數(shù)據(jù)3應(yīng)該出圈。

first繼續(xù)指向要出圈數(shù)據(jù)的下一個(gè)結(jié)點(diǎn),end所在的結(jié)點(diǎn)指向first指向的結(jié)點(diǎn),就讓數(shù)據(jù)3出圈了。

結(jié)點(diǎn)出圈后,first和end又同時(shí)指向一個(gè)結(jié)點(diǎn),m 又開始重新計(jì)數(shù) ,如此循環(huán)下去即可。

        Node end = first;
 
        while (true) {
            //當(dāng)總數(shù)只有一個(gè)的時(shí)候,循環(huán)結(jié)束。
            if (n == 1) {
                System.out.println("勝利者為" + first + "號(hào)");
                break;
            }
 
            //用for循環(huán),循環(huán)次數(shù)為 m - 1,因?yàn)楸旧硪獢?shù)一個(gè)數(shù)
            for (int i = 1; i <= m - 1; i++) {
                //first指向下一個(gè)結(jié)點(diǎn)
                first = first.next;
                //如果找到了要出圈的結(jié)點(diǎn),first是正好指向它的
                if (i == m - 1) {
                    //first指向的這個(gè)結(jié)點(diǎn)出圈
                    System.out.println(first + "號(hào)出圈");
                    //每出圈一個(gè),總數(shù)減一
                    n--;
                    //first繼續(xù)指向下一個(gè)結(jié)點(diǎn)
                    first = first.next;
                    //此時(shí)end還在出圈結(jié)點(diǎn)的前一個(gè)位置,end的next指向first
                    end.next = first;
                    //end也同樣指向first指向的結(jié)點(diǎn)
                    end = first;
                    break;
                }
                //如果沒有到要出圈的結(jié)點(diǎn),end繼續(xù)跟著first指向同一個(gè)結(jié)點(diǎn)
                end = first;
            }
        }

4、出圈方法完整代碼

    public void goOutCircle(int start,int m, int n){
        //首先確定圈的大小
        if (n >= 2 && start <= n){
            add(n);
        }else {
            System.out.println("輸入異常!");
            return;
        }
 
        //確定數(shù)數(shù)的位置
        Node temp = first;
        while (true){
            if (temp.data == start){
                first = temp;
                break;
            }
            temp = temp.next;
        }
 
        //進(jìn)行遍歷
        Node end = first;
        while (true) {
            if (n == 1) {
                System.out.println("勝利者為" + first + "號(hào)");
                break;
            }
 
            for (int i = 1; i <= m - 1; i++) {
                first = first.next;
                if (i == m - 1) {
                    System.out.println(first + "號(hào)出圈");
                    n--;
                    first = first.next;
                    end.next = first;
                    end = first;
                    break;
                }
                end = first;
            }
        }
    }

運(yùn)行結(jié)果:

總結(jié)

到此這篇關(guān)于Java數(shù)據(jù)結(jié)構(gòu)之環(huán)形鏈表和約瑟夫問題詳解的文章就介紹到這了,更多相關(guān)Java環(huán)形鏈表和約瑟夫問題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot自定義注解驗(yàn)證枚舉的實(shí)現(xiàn)

    SpringBoot自定義注解驗(yàn)證枚舉的實(shí)現(xiàn)

    本文主要介紹了SpringBoot自定義注解驗(yàn)證枚舉的實(shí)現(xiàn),數(shù)據(jù)校驗(yàn),需要對(duì)枚舉類型的數(shù)據(jù)傳參,進(jìn)行數(shù)據(jù)校驗(yàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • Java語言打印九九乘法表

    Java語言打印九九乘法表

    這篇文章主要為大家詳細(xì)介紹了Java語言打印九九乘法表的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • SpringBoot自定義starter啟動(dòng)器的實(shí)現(xiàn)思路

    SpringBoot自定義starter啟動(dòng)器的實(shí)現(xiàn)思路

    這篇文章主要介紹了SpringBoot如何自定義starter啟動(dòng)器,通過starter的自定義過程,能夠加深大家對(duì)SpringBoot自動(dòng)配置原理的理解,需要的朋友可以參考下
    2022-10-10
  • Java實(shí)現(xiàn)Fast DFS、服務(wù)器、OSS上傳功能

    Java實(shí)現(xiàn)Fast DFS、服務(wù)器、OSS上傳功能

    這篇文章主要介紹了Java實(shí)現(xiàn)Fast DFS、服務(wù)器、OSS上傳功能,在實(shí)際的業(yè)務(wù)中,可以根據(jù)客戶的需求設(shè)置不同的文件上傳需求,支持普通服務(wù)器上傳+分布式上傳(Fast DFS)+云服務(wù)上傳OSS(OSS),需要的朋友可以參考下
    2024-04-04
  • Kafka攔截器的神奇操作方法

    Kafka攔截器的神奇操作方法

    Kafka攔截器是一種強(qiáng)大的機(jī)制,用于在消息發(fā)送和接收過程中插入自定義邏輯,它們可以用于消息定制、日志記錄、監(jiān)控、業(yè)務(wù)邏輯集成、性能統(tǒng)計(jì)和異常處理等,本文介紹Kafka攔截器的神奇操作,感興趣的朋友一起看看吧
    2025-01-01
  • SpringBoot?緩存預(yù)熱的實(shí)現(xiàn)

    SpringBoot?緩存預(yù)熱的實(shí)現(xiàn)

    本文主要介紹了SpringBoot?緩存預(yù)熱的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2007-11-11
  • HttpClient實(shí)現(xiàn)表單提交上傳文件

    HttpClient實(shí)現(xiàn)表單提交上傳文件

    這篇文章主要為大家詳細(xì)介紹了HttpClient實(shí)現(xiàn)表單提交上傳文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • JVM:你知道為什么對(duì)象一定在堆中分配嗎

    JVM:你知道為什么對(duì)象一定在堆中分配嗎

    這篇文章主要介紹了jvm對(duì)象的創(chuàng)建和分配的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下,希望能夠給你帶來幫助
    2021-08-08
  • Spring注解@Value在controller無法獲取到值的解決

    Spring注解@Value在controller無法獲取到值的解決

    這篇文章主要介紹了Spring注解@Value在controller無法獲取到值的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java中子類調(diào)用父類構(gòu)造方法的問題分析

    Java中子類調(diào)用父類構(gòu)造方法的問題分析

    本篇文章介紹了,Java中子類調(diào)用父類構(gòu)造方法的問題分析。需要的朋友參考下
    2013-04-04

最新評(píng)論

北川| 夏河县| 太白县| 宿迁市| 石首市| 呈贡县| 凉山| 卓尼县| 宿州市| 桦南县| 新乡县| 唐山市| 汽车| 舟曲县| 栖霞市| 日照市| 正宁县| 镇雄县| 芦溪县| 兴仁县| 五原县| 六安市| 花莲市| 安陆市| 湾仔区| 巴南区| 赞皇县| 铜陵市| 高阳县| 五大连池市| 鄂尔多斯市| 东台市| 仪陇县| 旬阳县| 阿城市| 睢宁县| 海伦市| 固安县| 宁强县| 库尔勒市| 大同县|