本章要求有以下預備知識:線性表的順序儲存結構之順序表類的實現_Java
今天我們來使用順序表類求解約瑟夫(Josephus)環問題。
首先我閑來描述下約瑟夫環問題:古代某法官要裁決n個犯人的死刑,他有一條荒唐的法律,將犯人站成一個圓圈,從第s個人開始數起,每數到第d個犯人,就拉出來處決,然後再從下一個開始數d個,數到的人再處決,……,知道剩下最後一個犯人予以赦免。
使用順序表類SeqList求解約瑟夫環問題,演算法描述如下:
建立一個具有n個元素的順序表對象list。
從第s個元素開始,依次計數,每數到d,就將對應元素刪除。
重複計數並刪除元素,直到剩下一個元素。
設index表示順序表元素序號,計數時,使index按照以下規律變化,則數序表可以看成是環型結構:
index = (index + d-1) % list.length();
在聲明和建立SeqList對象時,指定泛型E為一個類。程式如下:
import dataStructure.linearList.LList;import dataStructure.linearList.SeqList;;public class Josephus//求解約瑟夫環問題{private LList<String> list;//儲存約瑟夫環中的多個對象public Josephus(int number,int start,int distance)//建立約瑟夫環並求解,參數指定環長度、起始位置、計數{this.list = new SeqList<String>(number);//順序表元素類型是字串,指定容量for(int i = 0;i < number;i ++)this.list.add(new String((char)('A' + i) + ""));//添加字串對象System.out.print("約瑟夫環(" + number + "," + start + "," + distance + "),");System.out.println(this.list.toString());//顯示順序表所有對象的字串表示int index = start - 1;//計數起始位置while (this.list.length() > 1)//多於一個對象時迴圈{index = (index + distance - 1) % this.list.length();System.out.print("刪除" + this.list.remove(index).toString() + ",");//刪除指定位置對象System.out.println(this.list.toString());}System.out.println("被赦免者是" + list.get(0).toString());}public static void main(String[] args){new Josephus(10, 1, 3);}}
程式運行結果如下:
約瑟夫環(10,1,3),(A,B,C,D,E,F,G,H,I,J)
刪除C,(A,B,D,E,F,G,H,I,J)
刪除F,(A,B,D,E,G,H,I,J)
刪除I,(A,B,D,E,G,H,J)
刪除B,(A,D,E,G,H,J)
刪除G,(A,D,E,H,J)
刪除A,(D,E,H,J)
刪除H,(D,E,J)
刪除E,(D,J)
刪除J,(D)
被赦免者是D
下一章中我將和大家探討線性表的鏈式儲存結構——單鏈表的結點類的寫法