經典的Fisher-Yates Shuffle算法


 

回頭看酷殼上那篇《一些有意思的算法代碼》,在清單上看到第一條是Binomial Heap,回想一下好像是算法導論里剛剛研習過的內容,對,是二項堆,特別想看看具體的實現,點開鏈接看到滿滿的注釋,頓時幸福洋溢。再看作者,Keith Schwarz,他是一個斯坦福大學計算機科學系的講師,在自己的網站放了一些自己實現的算法和數據結構,覺得挺好的,有空可以去看看,這是鏈接:http://www.keithschwarz.com/interesting/

改天再談談二項堆的內容,今天先貼一個應該是其中最短的代碼,Random Shuffle隨機洗牌,隨便學習一下算法和C++。(這位老師還非常願意分享自己的代碼,只是注滿注釋的代碼顯得太長了)

 

代碼注釋很多也很淺顯,就不翻譯了。雖說核心的代碼就兩行,但是里面的所有內容還是很應該學習的,比如,可以在自選范圍內進行隨機排列,可以傳入自定義的隨機數產生算法,使用了模板這樣任何數據類型都可以進行排列。這個算法核心的意思也就一句話來概括:隨機選取一個數組元素,和第一個元素進行交換,然后繼續按照這種方法處理剩下的數組元素,只需要線性時間和常量空間即可。

這里面還有一點沒有想到的是,在函數參數列表里居然可以傳入函數名稱,然后在里面執行這個傳入的函數,難道是函數指針,C++真是忘得差不多了。

 

==================================================================================

/**************************************************************************
 * File: RandomShuffle.hh
 * Author: Keith Schwarz (htiek@cs.stanford.edu)
 *
 * An implemention of a function for randomly permuting the elements of a
 * sorted range.  The algorithm is an implementation of the Fisher-Yates
 * shuffle (also called the Knuth shuffle), which works by randomly selecting
 * an element from the the array and swapping it to the front, then recursively
 * repeating the process on the rest of the array.  It runs in linear time
 * and with only constant space.
 *
 * This implementation, by default, works using the system rand function,
 * which is not ideal if cryptographic randomness is desired.  Consequently,
 * like the STL algorithm random_shuffle, the algorithm allows for a custom
 * random generator to be passed into the function.
 */

#ifndef RandomShuffle_Included
#define RandomShuffle_Included

#include <algorithm> // For iter_swap
#include <cstdlib>   // For rand

/**
 * Function: RandomShuffle(RandomIterator begin, RandomIterator end);
 * ------------------------------------------------------------------------
 * Randomly permutes the elements in the range [begin, end), using the system
 * rand function as a source of randomness.
 */

template <typename RandomIterator>
void RandomShuffle(RandomIterator begin, RandomIterator end);

/**
 * Function: RandomShuffle(RandomIterator begin, RandomIterator end,
 *                         RandomGenerator rng);
 * ------------------------------------------------------------------------
 * Randomly permutes the elements in the range [begin, end), using the
 * provided callback as a source of randomness.  The generator should be
 * callable as a nullary function which produces a uniformly-distributed
 * random value over a range at least as large as the input range.
 */

template <typename RandomIterator, typename RandomGenerator>
void RandomShuffle(RandomIterator begin, RandomIterator end,
                   RandomGenerator rnd);

/* * * * * Implementation Below This Point * * * * */

/* Main implementation of the algorithm. */
template <typename RandomIterator, typename RandomGenerator>
void RandomShuffle(RandomIterator begin, RandomIterator end,
                   RandomGenerator rnd) {
  /* Iterate across the elements, picking a random element and swapping it
   * to the front at each step.
   */

  for (RandomIterator itr = begin; itr != end; ++itr)
    std::iter_swap(itr, itr + rnd() % (end - itr));
}

/* Default implementation just uses rand. */
template <typename RandomIterator>
void RandomShuffle(RandomIterator begin, RandomIterator end) {
  RandomShuffle(begin, end, std::rand);
}

#endif

==================================================================================

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM