java數據結構與算法之循環單鏈表

循環單鏈表解決約瑟夫問題

package cn.agan.link;

/**
 * 約瑟夫問題:
 * 據說著名猶太歷史學家 Josephus有過以下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,
 * 39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,
 * 然後再由下一個重新報數,直到所有人都自殺身亡爲止。然而Josephus 和他的朋友並不想遵從。首先從一個人開始,越過k-2個人(因爲第一個人已經被越過),
 * 並殺掉第k個人。接着,再越過k-1個人,並殺掉第k個人。這個過程沿着圓圈一直進行,直到最終只剩下一個人留下,這個人就可以繼續活着。
 * 問題是,給定了和,一開始要站在什麼地方纔能避免被處決?Josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,
 * 於是逃過了這場死亡遊戲
 * 簡言之: N個人圍成一圈,從第一個開始報數,第M個將被殺掉,最後剩下一個,其餘人都將被殺掉。例如N=6,M=5,被殺掉的順序是:5,4,6,2,3,1。
 */

public class JosephuCircularLink {

    public static void main(String[] args) {
        SingleLinkList l = new SingleLinkList();
        l.fullPersion(6);
        l.show();
        l.killCircular(2);
    }

}


//單向環形鏈表
class SingleLinkList {
    private Person first;

    public void add(Person p) {
        if (first == null) {
            first = p;
            p.setNext(p);
            return;
        }

        Person tmp = first.getNext();
        while (tmp.getNext() != first) {
            tmp = tmp.getNext();
        }
        p.setNext(tmp.getNext());
        tmp.setNext(p);
    }

    //約瑟夫殺人
    public void killCircular(int M) {

        if (first == null || M < 1 ) {
            System.out.println("沒有人可以被殺害");
            return ;
        }

        Person prevP = first.getNext();
        while (prevP.getNext() != first) {
            prevP = prevP.getNext();
        }

        while (true) {
            if (prevP == first) {
                break;
            }

            for (int i = 1; i < M; i++) {
                prevP = prevP.getNext();
                first = first.getNext();
            }
            System.out.println(first.getNo()+"被殺");
            prevP.setNext(first.getNext());

            first = prevP.getNext();
        }

        System.out.println("最後存活的是"+first.getNo());
    }

    public void fullPersion(int num) {
        if (num < 1) {
            System.out.println("參數有誤");
            return;
        }

        for (int i = 0; i < num; i++) {
            Person p = new Person(i+1, "我是"+(i+1));
            add(p);
        }

    }

    public void show() {
        System.out.println(first+"\t");
        Person p = first.getNext();
        while (p != first) {
            System.out.println(p+"\t");
            p = p.getNext();
        }
    }

}

//人
class Person  {
    private int no;
    private String name;
    private Person next;

    public Person(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person getNext() {
        return next;
    }

    public void setNext(Person next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Person{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章