ページ 11

配列をポインタを用いて昇順に並べ替える

Posted: 2016年5月14日(土) 03:08
by ちゃん
質問失礼します。
main関数の中にある配列を man関数に渡して昇順に並べ替えたいのですが、こちらのコードで間違ってはいないでしょうか。
コンパイルは通ります。
しかし、ネットで調べてみると 変数i を使って for(i = 0; i < 10; i++) のようにfor文で回しているコードが多く見られます。
どちらのほうが賢い書き方なのでしょうか。

どなたかご教授お願いいたします。

コード:

#include <stdio.h>
#define DSIZE 10

void man(int *);

void man(int *tana)
{
	int num, *point;

	for(point = tana; point < &point[DSIZE - 1]; point++)
	{
		if(*point > *(point + 1))
		num = *point;
		*point = *(point + 1);
		*(point + 1) = num;
	}
}

int main(void)
{
       int array[] = { 1, -2, 3, -5, 7, -11, 13, -15, 17, -19 };

       man(array);
       return 0;
}


Re: 配列をポインタを用いて昇順に並べ替える

Posted: 2016年5月14日(土) 05:20
by box
昇順に並べ替えた結果を出力していないので、何とも言いがたいです。
man関数を通した後のarrayを出力して昇順になっていれば、そのman関数で
正しい、ということが検証できると思います。

Re: 配列をポインタを用いて昇順に並べ替える

Posted: 2016年5月14日(土) 05:42
by box
ちゃん さんが書きました:

コード:

#define DSIZE 10
       int array[] = { 1, -2, 3, -5, 7, -11, 13, -15, 17, -19 };

       man(array);
私だったら、配列の要素数を10と決め打ちしないで、
man関数に配列の要素数も渡すかもしれません。

例えば
man(array, sizeof(array) / sizeof(array[0]);
のように。要するに、配列の要素数をコンピューターに数えさせるのです。
そうすればDSIZEは不要になって、かつ、配列の要素数によらずソートできるはずです。

ご提示のコードでは、配列の要素数が「10のときだけ」しか対応できないので、
いささか汎用性に欠けるのではないかと思います。

Re: 配列をポインタを用いて昇順に並べ替える

Posted: 2016年5月14日(土) 07:57
by みけCAT
  • 要素の交換っぽい部分(13~15行目)が、適切にブロックまたはカンマ演算子を使っていないため、データの破壊を起こしたり、入力によっては初期化されていない自動変数の値を使うことで未定義動作を起こす可能性があったります。
  • 「要素の交換っぽい部分」がもしも正しい要素の交換を行うコードだったとしても、O(N) (N = DSIZE)のループを1パスしか回しておらず、一般に正しくソートをすることはできません。基数ソートなどの「ズル」をせずに要素の比較によってソートを行う場合、O(N log N) (N = 要素数)以上かかることが知られています。
従って、このプログラムは間違っています。