スポンサーリンク

Fisher-Yatesのシャッフルアルゴリズムをc言語で実装

配列の要素をランダムに並べ替える手法として、Fisher-Yatesのシャッフルアルゴリズムが有名ですね。
ランダムに選ばれた配列の要素を、配列の末尾の要素と入れ替えます。
入れ替えは配列の最後尾から開始して、先頭の要素まで順次ループ処理します。
入れ替え対象の要素は、入れ替え済みの末尾の要素は対象外となります。
計算量はO(n)となります。

void shuffleArrayData(int* array, int size){
	int i, target, tmp;
	
	//最後尾から順次ループ処理
	for(i = size -1; i > 0; i--){
		//0~i番目の要素から、入れ替え対象の要素をランダムに選ぶ
		target = rand() % i;
		//ここから下は末尾の要素と入れ替え
		tmp = array[target];
		array[target] = array[i];
		array[i] = tmp;
	}
}

最後尾からループ処理することで、入れ替え対象の要素を選ぶコードが、下記のようにシンプルに書けますね。
実際に書いてみると感動します。

		target = rand() % i;

スポンサーリンク

サンプルコード

下記がサンプルコードになります。

$ cat sample.c 
#include <stdio.h>
#include <stdlib.h>

void shuffleArrayData(int* array, int size){
	int i, target, tmp;
	
	for(i = size -1; i > 0; i--){
		target = rand() % i;
		tmp = array[target];
		array[target] = array[i];
		array[i] = tmp;
	}
	
	for(i = 0; i < size; i++){
		printf("%d ", array[i]);
	}
}

int main(){
	int array[] = {4, 2, 8, 7, 1, 2, 3};
	//int array[] = {4, 2};
	//int array[] = {4};
	
	shuffleArrayData(array, (int)(sizeof(array) / sizeof(array[0])));
		
	return 0;
}

下記が実行結果になります。
$ gcc -o sample sample.c
$ ./sample 
2 7 4 8 3 1 2 

スポンサーリンク