链表(Linked List)之环形链表
原文地址:傳送門
單向環(huán)形鏈表應(yīng)用場(chǎng)景
Josephu(約瑟夫、約瑟夫環(huán)) 問題
Josephu 問題為:設(shè)編號(hào)為1,2,… n的n個(gè)人圍坐一圈,約定編號(hào)為k(1<=k<=n)的人從1開始報(bào)數(shù),數(shù)到m 的那個(gè)人出列,它的下一位又從1開始報(bào)數(shù),數(shù)到m的那個(gè)人又出列,依次類推,直到所有人出列為止,由此產(chǎn)生一個(gè)出隊(duì)編號(hào)的序列。
提示:
用一個(gè)不帶頭結(jié)點(diǎn)的循環(huán)鏈表來處理Josephu 問題:先構(gòu)成一個(gè)有n個(gè)結(jié)點(diǎn)的單循環(huán)鏈表,然后由k結(jié)點(diǎn)起從1開始計(jì)數(shù),計(jì)到m時(shí),對(duì)應(yīng)結(jié)點(diǎn)從鏈表中刪除,然后再?gòu)谋粍h除結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)又從1開始計(jì)數(shù),直到最后一個(gè)結(jié)點(diǎn)從鏈表中刪除算法結(jié)束。
Josephu 問題為:設(shè)編號(hào)為1,2,… n的n個(gè)人圍坐一圈,約定編號(hào)為k(1<=k<=n)的人從1開始報(bào)數(shù),數(shù)到m 的那個(gè)人出列,它的下一位又從1開始報(bào)數(shù),數(shù)到m的那個(gè)人又出列,依次類推,直到所有人出列為止,由此產(chǎn)生一個(gè)出隊(duì)編號(hào)的序列。
n = 5 , 即有5個(gè)人 k = 1, 從第一個(gè)人開始報(bào)數(shù) m = 2, 數(shù)2下構(gòu)建一個(gè)單向的環(huán)形鏈表思路
遍歷環(huán)形鏈表
環(huán)形鏈表_約瑟夫問題分析圖解和實(shí)現(xiàn)
根據(jù)用戶的輸入,生成一個(gè)小孩出圈的順序 n = 5 , 即有5個(gè)人 k = 1, 從第一個(gè)人開始報(bào)數(shù) m = 2, 數(shù)2下原來first 指向的節(jié)點(diǎn)就沒有任何引用,就會(huì)被回收
出圈的順序 2->4->1->5->3
一直丟手絹
代碼
package com.atguigu.linkedlist;/*** ClassName: <br/>* Description: <br/>* Date: 2021-02-19 15:22 <br/>* @project data_algorithm* @package com.atguigu.linkedlist*/public class Josepfu {public static void main(String[] args) {// 測(cè)試一把看看構(gòu)建環(huán)形鏈表,和遍歷是否okCircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();circleSingleLinkedList.addBoy(125);// 加入5個(gè)小孩節(jié)點(diǎn)circleSingleLinkedList.showBoy();//測(cè)試一把小孩出圈是否正確circleSingleLinkedList.countBoy(10, 20, 125); // 2->4->1->5->3//String str = "7*2*2-5+1-5+3-3";}}// 創(chuàng)建一個(gè)環(huán)形的單向鏈表 class CircleSingleLinkedList {// 創(chuàng)建一個(gè)first節(jié)點(diǎn),當(dāng)前沒有編號(hào)private Boy first = null;// 添加小孩節(jié)點(diǎn),構(gòu)建成一個(gè)環(huán)形的鏈表public void addBoy(int nums) {// nums 做一個(gè)數(shù)據(jù)校驗(yàn)if (nums < 1) {System.out.println("nums的值不正確");return;}Boy curBoy = null; // 輔助指針,幫助構(gòu)建環(huán)形鏈表// 使用for來創(chuàng)建我們的環(huán)形鏈表for (int i = 1; i <= nums; i++) {// 根據(jù)編號(hào),創(chuàng)建小孩節(jié)點(diǎn)Boy boy = new Boy(i);// 如果是第一個(gè)小孩if (i == 1) {first = boy;first.setNext(first); // 構(gòu)成環(huán)curBoy = first; // 讓curBoy指向第一個(gè)小孩} else {curBoy.setNext(boy);//boy.setNext(first);//curBoy = boy;}}}// 遍歷當(dāng)前的環(huán)形鏈表public void showBoy() {// 判斷鏈表是否為空if (first == null) {System.out.println("沒有任何小孩~~");return;}// 因?yàn)閒irst不能動(dòng),因此我們?nèi)匀皇褂靡粋€(gè)輔助指針完成遍歷Boy curBoy = first;while (true) {System.out.printf("小孩的編號(hào) %d \n", curBoy.getNo());if (curBoy.getNext() == first) {// 說明已經(jīng)遍歷完畢break;}curBoy = curBoy.getNext(); // curBoy后移}}// 根據(jù)用戶的輸入,計(jì)算出小孩出圈的順序/**** @param startNo* 表示從第幾個(gè)小孩開始數(shù)數(shù)* @param countNum* 表示要數(shù)幾下* @param nums * 表示最初有多少小孩在圈中*/public void countBoy(int startNo, int countNum, int nums) {// 先對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)if (first == null || startNo < 1 || startNo > nums) {System.out.println("參數(shù)輸入有誤, 請(qǐng)重新輸入");return;}// 創(chuàng)建要給輔助指針,幫助完成小孩出圈Boy helper = first;// 需求創(chuàng)建一個(gè)輔助指針(變量) helper , 事先應(yīng)該指向環(huán)形鏈表的最后這個(gè)節(jié)點(diǎn)while (true) {if (helper.getNext() == first) { // 說明helper指向最后小孩節(jié)點(diǎn)break;}helper = helper.getNext();}//小孩報(bào)數(shù)前,先讓 first 和 helper 移動(dòng) k - 1次for(int j = 0; j < startNo - 1; j++) {first = first.getNext();helper = helper.getNext();}//當(dāng)小孩報(bào)數(shù)時(shí),讓first 和 helper 指針同時(shí) 的移動(dòng) m - 1 次, 然后出圈//這里是一個(gè)循環(huán)操作,知道圈中只有一個(gè)節(jié)點(diǎn)while(true) {if(helper == first) { //說明圈中只有一個(gè)節(jié)點(diǎn)break;}//讓 first 和 helper 指針同時(shí) 的移動(dòng) countNum - 1for(int j = 0; j < countNum - 1; j++) {first = first.getNext();helper = helper.getNext();}//這時(shí)first指向的節(jié)點(diǎn),就是要出圈的小孩節(jié)點(diǎn)System.out.printf("小孩%d出圈\n", first.getNo());//這時(shí)將first指向的小孩節(jié)點(diǎn)出圈first = first.getNext();helper.setNext(first); //}System.out.printf("最后留在圈中的小孩編號(hào)%d \n", first.getNo());} }// 創(chuàng)建一個(gè)Boy類,表示一個(gè)節(jié)點(diǎn) class Boy {private int no;// 編號(hào)private Boy next; // 指向下一個(gè)節(jié)點(diǎn),默認(rèn)nullpublic Boy(int no) {this.no = no;}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;}}原文地址:傳送門
總結(jié)
以上是生活随笔為你收集整理的链表(Linked List)之环形链表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php多文件上传存储到表,PHP 实现一
- 下一篇: 爱普生R230打印机故障大全