ソートの効率性比較

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
may

ソートの効率性比較

#1

投稿記事 by may » 14年前

C言語 Linux gcc

課題
ファイルにあるデータを配列に格納し、下記の4種類の整列アルゴリズムを用いて整列する。このとき移動回数および実行時間(clock関数)を記録する。
   (1) 単純挿入法    (2) 単純選択法
   (3) バブルソート    (4) クイックソート

ファイルには整数がランダムに10,000コあります。
ex.
6378
90042
32786
31124
89571
3867




一度自分で作って、時間計測はうまくいきましたが、単純挿入法の移動回数は多く、単純選択法もわずかに多く、クイックソートは移動回数が少ないといわれました。
移動回数をカウントする場所は間違っていないと思うので、メイン関数内で間違えている気がするのですが、いくら考えても分からないので教えてください。
よろしくお願いします。

コード:

#include<time.h> 
#include<stdio.h> 
#include<stdlib.h> 
#define SIZE 10000

int sort_insert(int size, int *array);
int sort_select(int size, int *array);
int sort_buble(int size, int *array);
int sort_quick(int low, int high, int *array);
int count;

int main(){

  FILE *fp;
  int array1[SIZE],array2[SIZE],array3[SIZE],array4[SIZE];
  char buf[256];
  int i, j, s;
  clock_t start = 0, end = 0;

  if((fp = fopen("/home/sample/gotoh/integer10KR.dat", "r")) == 0){
    printf("ファイルが開けません\n");
    exit(0);
  }

  for(i=0; i < SIZE; i++){
    array1[i]=array1[i];
    array2[i]=array1[i];
    array3[i]=array1[i];
    array4[i]=array1[i];
  }

  start = clock();
  count = sort_insert(i,array1);
  end = clock();
  printf("単純挿入法\n移動回数:%d\n",count);
  printf("移動時間:%lf\n",(float)(end-start)/CLOCKS_PER_SEC);

  start = clock();
  count = sort_select(i,array2);
  end = clock();
  printf("単純選択法\n 移動回数:%d\n",count);
  printf("移動時間:%lf\n",(float)(end-end)/CLOCKS_PER_SEC);

  start = clock();
  count = sort_buble(i,array3);
  end = clock();
  printf("バブルソート\n 移動回数:%d\n",count);
  printf("移動時間:%lf\n",(float)(end-start)/CLOCKS_PER_SEC);

  start = clock();
  count = sort_quick(0, SIZE - 1, array4);
  end = clock();
  printf("クイックソート\n 移動回数:%d\n",count);
  printf("移動時間:%lf\n",(float)(end-start)/CLOCKS_PER_SEC);

  fclose(fp);

  return 0;
}

int sort_insert(int size, int *array) { // 単純挿入法
  int i, // 未整列の列の指標
      j, // 整列済みの列の指標
      x, // 未整列の列の比較要素 
    count = 0;
  for(i = 1 ; i < size; i++){ // 未整列の列から要素を取り出す 
    x = array[i]; // 未整列の最初の要素を取り出す 
    ++count;
    j = i;
    while( 0 < j && x < array[j - 1]){ // 整列済み列の後方から比較 
      array[j] = array[j - 1]; // 整列済み列の要素を後方へずらす 
      ++count;
      j--; // 整列済み列の指標を前方へ移動 
    }
    array[j] = x; // 比較要素を整列済み列に代入(挿入) 
    ++count;
  }
  return count;
}

int sort_select(int size, int *array) { // 単純選択法 
  int i, // 未整列の列の指標 
    j, // 整列済みの列の指標 
    pos, // 未整列の最小要素の位置 
    x,
    count = 0; 
  for(i = 0; i < size; i++){
    x = array[i]; // 比較要素に初期値を代入 
    ++count;
    for(j = i + 1; j < size; j++){ // 未整列中の最小要素を探す 
      if (array[j] < x){ // 対象要素が比較要素より大 
	x = array[j]; // 比較要素を入替え 
	++count;
	pos = j; // 比較要素の位置を代入 
      }
    }
    if (array[i] != x){
      array[pos] = array[i]; // 最小要素の位置に先頭要素を代入 
      ++count;
      array[i] = x; // 先頭要素と最小要素を入替え 
      ++count;
    }
  }
  return count;
}

int sort_buble(int size, int *array) { // バブルソ-ト 
  int i, // 未整列の列の指標 
    x, // 交換用の変数 
    j; // 整列済みの列の指標
  int count = 0; 
  for(i = 0; i < size; i++){
    for(j = size - 1; j > i; --j){
      if (array[j - 1] >= array[j]){ // 前要素が対象要素よりも小 
	x = array[j - 1];
	++count;
	array[j - 1] = array[j]; // 前の要素と入替え 
	++count;
	array[j] = x;
	++count;
      }
    }
  }
  return count;
}

int sort_quick(int low, int high, int *array) { // クイックソート 
  int i, // 対象要素の指標(先頭方向) 
      j, // 対象要素の指標(末尾方向) 
      mid, // 対象配列の中央の値=比較要素 
      tmp; // 入替え用 
  int count = 0;
  i = low;
  j = high;
  mid = array[(low + high) / 2]; // 比較要素 
  ++count;
  do{
   while(array[i] < mid)
     i++; // 比較要素より大きい要素を探索 
   while(mid < array[j])
     j--; // 比較要素より小さい要素を探索 
   if (i <= j){ // 2つの指標が交差するまで 
     tmp = array[i];
     ++count;
     array[i] = array[j]; // 大きい要素と小さい要素を交換 
     ++count;
     array[j] = tmp;
     ++count;
     i++;
     j--;
   }
  }while(i <= j);
   if (low < j)
     sort_quick(low, j, array); // 前半部についてソート 
   if (i < high)
     sort_quick(i, high, array); // 後半部についてソート
   return count;
}

box
記事: 2002
登録日時: 15年前

Re: ソートの効率性比較

#2

投稿記事 by box » 14年前

ぱっと見ておかしそうだなぁと思うのは、下記3点です。他にもいくつかありますが、とりあえず影響が大きそうなところだけ。
1)データファイルは、オープン・クローズしているだけで、読み込んでいる形跡がない。
2)array1[]に値をセットしている形跡がない。

>ファイルにあるデータを配列に格納し
これを行なってないんだから、そりゃ結果はおかしいですよね。

3)クイックソートで、再帰呼び出しのたびに回数をゼロで初期化してしまっている。

回数を少なくカウントして当然ですね。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

“C言語何でも質問掲示板” へ戻る