プログラミング修行その1:バブルソート
たまには基本的なアルゴリズムの復習をしとかないと忘れるw
まずは簡単なバブルソートからやってみる。
練習としてCで実装した。
配列内に値が格納されているとする。
バブルソートは、左の値が右の値より大きければ入れ替えるだけ。
それを左端から右端までやる。
そうすると最大値が右端に来る。
これを配列の要素数-1だけ繰り返す。
そんだけw
バブルソートの実装はすぐにできた。
むしろファイルの読み込みとかで苦戦したorz
Cメンドクセー!
テスト用のファイルは2つ。
1行目の値はソートする値の数。
「sorting.txt」
100 14.87764 79.91459 32.04577 52.47648 37.37609 92.92702 95.66952 12.44020 79.36001 58.55178 45.7271 50.34571 64.64258 44.16959 80.47934 77.84812 36.76213 59.63012 14.71282 51.97675 23.64163 8.721956 29.20096 4.217992 45.30573 77.46075 62.69849 7.304937 41.10914 88.78288 78.64944 28.69343 20.21519 86.04278 86.71323 73.7722 32.83814 32.05642 50.90693 93.62222 33.20098 19.04709 24.12797 57.44827 8.226496 3.016102 18.80332 63.08548 32.34478 48.01698 75.35823 59.00964 88.93037 88.97937 40.26842 10.32882 54.73123 45.87262 68.84773 70.79227 0.2335615 70.41457 13.86259 62.18793 73.53001 67.42753 50.306 65.18794 5.185891 41.06601 90.83678 53.06632 50.26822 81.68491 92.29141 85.35683 80.62988 20.71659 44.08074 14.66574 7.861154 23.08027 88.06054 73.81652 96.86138 58.21597 3.407331 56.66343 67.48117 50.70082 56.70293 36.16603 15.31543 31.35736 68.83037 10.46522 23.64201 56.16076 75.30015 60.66254
途中経過を見たい場合は次のファイルを使う。
さすがに100個のデータのソートの途中経過は見たくないw
「sorting2.txt」
10 59 13 38 91 48 27 66 45 13 38
で、これがCで実装したコード
#include <stdio.h> #include <stdlib.h> #include <string.h> #define LENGTH 200 // 1行の文字数 void print_numbers(double *numbers,int size); // 配列内の値を表示 int my_bubble_sort(double *numbers,int size); // バブルソート関数 int my_bubble_sort2(double *numbers,int size); // バブルソート関数(途中経過表示) int main(int argc, char *argv[]) { FILE *input; char str[LENGTH]; char *p; int size; // ソートする値の数 double num; double *numbers; int cnt; // パラメータのチェック if( argc != 3 || argv[1][0] != '-'){ printf("%s%s%s%s", "パラメータが不適切です。\n", "使用法:mySorting <アルゴリズム> <ファイル名>\n", "アルゴリズムの指定\n", "\t-b バブルソート" ); return 0; } // 入力ファイルを開く if( (input = fopen( *(argv+2), "r") ) == NULL){ printf("Open Input File Error.\n"); return 0; } // 値を配列に格納する if( fgets(str,LENGTH,input) == NULL ){ printf("Read Input File Error.\n"); return 0; } size = atoi(str); printf("size = %d\n",size); // 値の数の確認 numbers = malloc( sizeof(double)*size);// 配列の動的確保 cnt = 0; while( fgets(str,LENGTH,input) != NULL ){ p = strtok(str," "); while( p != NULL){ num = atof(p); numbers[cnt] = num; cnt++; p = strtok(NULL," "); } } // 配列に格納された値を出力して確認 print_numbers(numbers,size); // 入力ファイルを閉じる if( fclose(input)==EOF ){ printf("Close Input File Error.\n"); return 0; } // アルゴリズムの実行 switch(argv[1][1]) { case 'b': printf("バブルソート(bubble sort)\n"); my_bubble_sort(numbers,size); break; case 'B': printf("バブルソート(bubble sort)\n"); my_bubble_sort2(numbers,size); break; default: printf("アルゴリズムの指定が不適切です。\n"); return 0; } // ソート後の配列に格納された値を出力して確認 // ソート後、左の値が右の値より大きければエラー printf("ソート完了\n"); for(cnt = 0; cnt < size; cnt++){ printf(" %f",numbers[cnt]); if( cnt != 0 && numbers[cnt-1] > numbers[cnt] ){ printf("\nerror.\n"); return 0; } if( (cnt+1) % 5 == 0 ){ printf("\n"); } } return 0; } // 配列内の値を表示 void print_numbers(double *numbers,int size) { int cnt; for(cnt = 0; cnt < size; cnt++){ printf(" %f",numbers[cnt]); if( (cnt+1) % 5 == 0 ){ printf("\n"); } } } // バブルソート関数 int my_bubble_sort(double *numbers,int size) { double keep; int i,j; for(j = 0; j < size-1; j++){ for( i = 0; i < (size-j-1); i++){ if( numbers[i] > numbers[i+1] ){ keep = numbers[i]; numbers[i] = numbers[i+1]; numbers[i+1] = keep; } } } return 0; } // バブルソート関数2(途中経過を表示) int my_bubble_sort2(double *numbers,int size) { double keep; int i,j,k; for(j = 0; j < size-1; j++){ for( i = 0; i < (size-j-1); i++){ if( numbers[i] > numbers[i+1] ){ keep = numbers[i]; numbers[i] = numbers[i+1]; numbers[i+1] = keep; print_numbers(numbers,size); printf("\n"); } } } return 0; }
実行結果
「sorting.txt」での実行結果
C:\C_syugyo>mySorting -b mysorting.txt size = 100 14.877640 79.914590 32.045770 52.476480 37.376090 92.927020 95.669520 12.440200 79.360010 58.551780 45.727100 50.345710 64.642580 44.169590 80.479340 77.848120 36.762130 59.630120 14.712820 51.976750 23.641630 8.721956 29.200960 4.217992 45.305730 77.460750 62.698490 7.304937 41.109140 88.782880 78.649440 28.693430 20.215190 86.042780 86.713230 73.772200 32.838140 32.056420 50.906930 93.622220 33.200980 19.047090 24.127970 57.448270 8.226496 3.016102 18.803320 63.085480 32.344780 48.016980 75.358230 59.009640 88.930370 88.979370 40.268420 10.328820 54.731230 45.872620 68.847730 70.792270 0.233562 70.414570 13.862590 62.187930 73.530010 67.427530 50.306000 65.187940 5.185891 41.066010 90.836780 53.066320 50.268220 81.684910 92.291410 85.356830 80.629880 20.716590 44.080740 14.665740 7.861154 23.080270 88.060540 73.816520 96.861380 58.215970 3.407331 56.663430 67.481170 50.700820 56.702930 36.166030 15.315430 31.357360 68.830370 10.465220 23.642010 56.160760 75.300150 60.662540 バブルソート(bubble sort) ソート完了 0.233562 3.016102 3.407331 4.217992 5.185891 7.304937 7.861154 8.226496 8.721956 10.328820 10.465220 12.440200 13.862590 14.665740 14.712820 14.877640 15.315430 18.803320 19.047090 20.215190 20.716590 23.080270 23.641630 23.642010 24.127970 28.693430 29.200960 31.357360 32.045770 32.056420 32.344780 32.838140 33.200980 36.166030 36.762130 37.376090 40.268420 41.066010 41.109140 44.080740 44.169590 45.305730 45.727100 45.872620 48.016980 50.268220 50.306000 50.345710 50.700820 50.906930 51.976750 52.476480 53.066320 54.731230 56.160760 56.663430 56.702930 57.448270 58.215970 58.551780 59.009640 59.630120 60.662540 62.187930 62.698490 63.085480 64.642580 65.187940 67.427530 67.481170 68.830370 68.847730 70.414570 70.792270 73.530010 73.772200 73.816520 75.300150 75.358230 77.460750 77.848120 78.649440 79.360010 79.914590 80.479340 80.629880 81.684910 85.356830 86.042780 86.713230 88.060540 88.782880 88.930370 88.979370 90.836780 92.291410 92.927020 93.622220 95.669520 96.861380
「sorting2.txt」での実行結果
C:\C_syugyo>mySorting -B mysorting2.txt size = 10 59.000000 13.000000 38.000000 91.000000 48.000000 27.000000 66.000000 45.000000 13.000000 38.000000 バブルソート(bubble sort) 13.000000 59.000000 38.000000 91.000000 48.000000 27.000000 66.000000 45.000000 13.000000 38.000000 13.000000 38.000000 59.000000 91.000000 48.000000 27.000000 66.000000 45.000000 13.000000 38.000000 13.000000 38.000000 59.000000 48.000000 91.000000 27.000000 66.000000 45.000000 13.000000 38.000000 13.000000 38.000000 59.000000 48.000000 27.000000 91.000000 66.000000 45.000000 13.000000 38.000000 13.000000 38.000000 59.000000 48.000000 27.000000 66.000000 91.000000 45.000000 13.000000 38.000000 13.000000 38.000000 59.000000 48.000000 27.000000 66.000000 45.000000 91.000000 13.000000 38.000000 13.000000 38.000000 59.000000 48.000000 27.000000 66.000000 45.000000 13.000000 91.000000 38.000000 13.000000 38.000000 59.000000 48.000000 27.000000 66.000000 45.000000 13.000000 38.000000 91.000000 13.000000 38.000000 48.000000 59.000000 27.000000 66.000000 45.000000 13.000000 38.000000 91.000000 13.000000 38.000000 48.000000 27.000000 59.000000 66.000000 45.000000 13.000000 38.000000 91.000000 13.000000 38.000000 48.000000 27.000000 59.000000 45.000000 66.000000 13.000000 38.000000 91.000000 13.000000 38.000000 48.000000 27.000000 59.000000 45.000000 13.000000 66.000000 38.000000 91.000000 13.000000 38.000000 48.000000 27.000000 59.000000 45.000000 13.000000 38.000000 66.000000 91.000000 13.000000 38.000000 27.000000 48.000000 59.000000 45.000000 13.000000 38.000000 66.000000 91.000000 13.000000 38.000000 27.000000 48.000000 45.000000 59.000000 13.000000 38.000000 66.000000 91.000000 13.000000 38.000000 27.000000 48.000000 45.000000 13.000000 59.000000 38.000000 66.000000 91.000000 13.000000 38.000000 27.000000 48.000000 45.000000 13.000000 38.000000 59.000000 66.000000 91.000000 13.000000 27.000000 38.000000 48.000000 45.000000 13.000000 38.000000 59.000000 66.000000 91.000000 13.000000 27.000000 38.000000 45.000000 48.000000 13.000000 38.000000 59.000000 66.000000 91.000000 13.000000 27.000000 38.000000 45.000000 13.000000 48.000000 38.000000 59.000000 66.000000 91.000000 13.000000 27.000000 38.000000 45.000000 13.000000 38.000000 48.000000 59.000000 66.000000 91.000000 13.000000 27.000000 38.000000 13.000000 45.000000 38.000000 48.000000 59.000000 66.000000 91.000000 13.000000 27.000000 38.000000 13.000000 38.000000 45.000000 48.000000 59.000000 66.000000 91.000000 13.000000 27.000000 13.000000 38.000000 38.000000 45.000000 48.000000 59.000000 66.000000 91.000000 13.000000 13.000000 27.000000 38.000000 38.000000 45.000000 48.000000 59.000000 66.000000 91.000000 ソート完了 13.000000 13.000000 27.000000 38.000000 38.000000 45.000000 48.000000 59.000000 66.000000 91.000000
うまくいったな。
改良できそうな部分もあるけどめんどいからほっとこうw