洗牌(shuffle)

洗牌(Shuffling)

假設你有一排順序排列的撲克牌,你要作的就是從新排序使得原有的順序排列變爲無序排列.java

  • 初始順序排列的撲克牌以下

撲克牌

洗牌排序(Shuffle sort)

步驟

  • 爲每一個撲克牌生成一個隨機數
  • 根據每一個撲克牌下的隨機數對撲克牌進行排序

示例

  • 初始撲克牌

撲克牌

  • 添加隨機數的撲克牌

撲克牌+隨機數

  • 根據撲克牌下的隨機數進行排序

撲克牌+隨機數+排序

Code by java

static public void shuffle(int a[]){
        TreeMap<Float,Integer> tm=new TreeMap<>();//使用Float(隨機數)--Integer(數字)鍵值對的map來存儲隨機數和數字的組合
                             //同時利用Treemap對鍵的排序功能對隨機數進行排序
        Random r=new Random();//建立Random對象
        for(int i=0;i<a.length;i++)//按順序給每一個數字一個隨機數,並添加到Treemap
            tm.put(r.nextFloat(),a[i]);
        int i=0;
        for(Float key:tm.keySet()) {//從Treemap中按順序取出值,並放入到原數組中
            a[i] = tm.get(key);
            i++;
        }
    }

特色

  • 排序的隨機性取決於隨機數生成的隨機性
  • 當遇到大規模洗牌,排序確實比較耗費時間

Knuth shuffle

步驟

  • 每第i次迭代,從第0-i個撲克牌中選擇隨機的一張牌與第i張牌交換

示例

  • i第i次迭代
  • r隨機產生介於的0-i的數字

Code by java

static public void kunthShuffle(int[] a){
        Random r=new Random();//建立Random對象
        int temp;//交換臨時變量
        for(int i=1;i<a.length;i++){//顯而易見下標爲0的數字不用交換
            int ri=r.nextInt(i+1);//隨機生成的0-i的下標
            temp=a[ri];//交換下標爲i和下標爲ri的兩個數
            a[ri]=a[i];
            a[i]=temp;
        }
    }

特色

  • 有效的對序列進行了隨機化
  • 可以在線性的時間內完成
相關文章
相關標籤/搜索