使用環(huán)形單向鏈表演示約瑟夫環(huán)問(wèn)題Scala版本

思路

約瑟夫環(huán)問(wèn)題 :
題目是 假設(shè)有N個(gè)小朋友按順序圍成一圈,每個(gè)小朋友都有一個(gè)編號(hào)愧口,假設(shè)從第m個(gè)小朋友從1開(kāi)始報(bào)數(shù)局义,報(bào)到k的小朋友出圈,從出圈的下一個(gè)小朋友繼續(xù)報(bào)數(shù)当窗,重復(fù)上面的報(bào)數(shù)够坐。直到所有的人出圈位置。
求出圈的小朋友的順序是什么

解決方案:
我們使用的是單向的環(huán)形鏈表作為數(shù)據(jù)結(jié)構(gòu)
思路大致分為

  1. 尋找指定開(kāi)始節(jié)點(diǎn)
  2. 跳動(dòng)指定的步長(zhǎng)-1(需要獲取彈出節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)崖面,才可以做刪除)
  3. 顯示彈出節(jié)點(diǎn)

代碼

package com.xipenhui.cn

import scala.collection.mutable.ArrayBuffer
import scala.util.control.Breaks._

/**
 * 約瑟夫環(huán)問(wèn)題 :
 * 題目是  假設(shè)有N個(gè)小朋友按順序圍成一圈元咙,每個(gè)小朋友都有一個(gè)編號(hào),假設(shè)從第m個(gè)小朋友從1開(kāi)始報(bào)數(shù)
 * 報(bào)到k的小朋友出圈巫员,從出圈的下一個(gè)小朋友繼續(xù)報(bào)數(shù)庶香,重復(fù)上面的報(bào)數(shù)。直到所有的人出圈位置疏遏。求出圈
 * 的小朋友的順序是什么
 * 解決方案:
 *   我們使用的是單向的環(huán)形鏈表作為數(shù)據(jù)結(jié)構(gòu)
 */
object JosephuDemo {
  def main(args: Array[String]): Unit = {

    val josephu = new Josephu()
    val boys = josephu.addBoy(5)
    println("=======創(chuàng)建出來(lái)的boys是=======")
    josephu.show()
    println("===彈出小朋友===")
    josephu.popBoy(2,3,5)
  }
}

/**
 * 環(huán)形單向鏈表
 * 1. 添加小孩子
 * 2. 按照規(guī)則彈出小孩子
 * 3. 顯示環(huán)形隊(duì)列的值脉课,做過(guò)程校驗(yàn)
 */
class Josephu {
  var head = Boy(-1)

  /**
   *
   * @param num 添加小孩的個(gè)數(shù)
   */
  def addBoy(num: Int) {

    //參數(shù)校驗(yàn)
    if (num < 1) {
      throw new RuntimeException("input num must big than 1")
    }

    var currBoy: Boy = null
    for (i <- 1 to num) {
      val boy = new Boy(i)
      if (i == 1) {
        head = boy
        head.next = head
        currBoy = boy
      } else {
        currBoy.next = boy
        boy.next = head
        currBoy = boy
      }
    }
  }


  /**
   * 按照給定的規(guī)律彈出元素
   * 1. 從開(kāi)始數(shù)到第m個(gè)小朋友,拿到當(dāng)前的小朋友
   * 2. 在當(dāng)前節(jié)點(diǎn)進(jìn)行后移财异,移動(dòng)到k個(gè)小朋友的前一個(gè)節(jié)點(diǎn)(單向鏈表刪除需要使用前一個(gè)節(jié)點(diǎn)輔助)
   *   彈出當(dāng)前小朋友倘零,刪除當(dāng)前節(jié)點(diǎn),
   * 3. 這里可以使用兩個(gè)for循環(huán)戳寸,
   *    第一次循環(huán)的長(zhǎng)度為鏈表長(zhǎng)度
   *    第二次循環(huán)的長(zhǎng)度為移動(dòng)的長(zhǎng)度 k -1 (因?yàn)橐耙粋€(gè)節(jié)點(diǎn))
   *
   * @param startNum 從第num個(gè)位置開(kāi)發(fā)數(shù)數(shù)字
   * @param countNum 數(shù)數(shù)的長(zhǎng)度為len
   * @param len      環(huán)形鏈表的長(zhǎng)度
   */
  def popBoy(startNum: Int, countNum: Int, len: Int): Unit = {
    //val resArr = ArrayBuffer[Boy]
    if (head.next == null || startNum < 1 || startNum > len) {
      println("輸入?yún)?shù)錯(cuò)誤呈驶,請(qǐng)重新輸入")
      System.exit(0)

    }
    var currBoy: Boy = head
    //可以找到起始位置的節(jié)點(diǎn)
    breakable {
      while (currBoy.next != head) {
        if (currBoy.num == startNum) {
          break()
        } else {
          currBoy = currBoy.next
        }
      }
    }
    if (currBoy.next == head) throw new RuntimeException("can not find input element")

    //點(diǎn)名的次數(shù)為 len次
    for (i <- 0 until len) {
      //從currBoy開(kāi)始點(diǎn)名,點(diǎn)名的長(zhǎng)度為countNum,這里是單向鏈表疫鹊,要借助前一個(gè)節(jié)點(diǎn)進(jìn)行刪除
      for (j <- 1 until countNum-1) {
        currBoy = currBoy.next
      }
      //這里 currBoy已經(jīng)移動(dòng)到需要移除節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)
      print(s"output element is ${currBoy.next.num} \n")
      currBoy.next = currBoy.next.next
      currBoy = currBoy.next
    }
  }

  //顯示當(dāng)前鏈表的內(nèi)容
  def show(): Unit = {
    var currBoy = head
     while (currBoy.next != head){
       println(s"input boy's num is ${currBoy.num}")
       currBoy=currBoy.next
     }
   println(s"input boy's num is ${currBoy.num}")
  }
}

case class Boy(num: Int) {
  var next: Boy = null
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末袖瞻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拆吆,更是在濱河造成了極大的恐慌聋迎,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枣耀,死亡現(xiàn)場(chǎng)離奇詭異霉晕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門牺堰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拄轻,“玉大人,你說(shuō)我怎么就攤上這事伟葫『薮辏” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵筏养,是天一觀的道長(zhǎng)斧抱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)撼玄,這世上最難降的妖魔是什么夺姑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮掌猛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘眉睹。我一直安慰自己荔茬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布竹海。 她就那樣靜靜地躺著慕蔚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪斋配。 梳的紋絲不亂的頭發(fā)上孔飒,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音艰争,去河邊找鬼坏瞄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛甩卓,可吹牛的內(nèi)容都是我干的鸠匀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼逾柿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缀棍!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起机错,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤爬范,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后弱匪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體青瀑,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狱窘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杜顺。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蘸炸,靈堂內(nèi)的尸體忽然破棺而出躬络,到底是詐尸還是另有隱情,我是刑警寧澤搭儒,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布穷当,位于F島的核電站,受9級(jí)特大地震影響淹禾,放射性物質(zhì)發(fā)生泄漏馁菜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一铃岔、第九天 我趴在偏房一處隱蔽的房頂上張望汪疮。 院中可真熱鬧,春花似錦毁习、人聲如沸智嚷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)盏道。三九已至,卻和暖如春载碌,著一層夾襖步出監(jiān)牢的瞬間猜嘱,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工嫁艇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朗伶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓裳仆,卻偏偏與公主長(zhǎng)得像腕让,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歧斟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355