2016-08-12 3 views
-1

私は簡単なコードを書いた。 bubbleSortはバブルソート関数(最小から最大)で、int intはサイズ5のint配列でこのコードをテストするために使用されます。C:配列へのポインタと破壊的な並べ替え

私はこれを破壊的にソートしたい単純にコピーを通過するだけではありません。私は見て見ましたが、これがどう動くべきかはまだ完全にはわかりません。私はここで何が欠けていますか?

#include <stdio.h> 

void bubbleSort(int values[], int n); 

int main(void) { 
//set simple test array to make sure bubbleSort works 
    int arr[5] = {5,4,3,2,1}; 
//run it through function, and then print the now sorted array to make sure 
    bubbleSort(arr, 5); 
    printf("%i", arr); 
    return 0; 
} 


void bubbleSort(int values[], int n) 
{ 
    for (int i = 0; i < n; i++) { 
     for (int j = 0, hold = 0; j < n-i; j++) { 
      if (values[j] > values[j+1]) { 
       hold = values[j+1]; 
       values[j+1] = values[j]; 
       values[j] = hold; 
      } 
     } 
    } 
    return; 
} 

注:私のコードの残りの部分は、私のアマチュアコーディングの心に音に見えますが、私が改善することができるものでポインタを与えてください、より良い何をすることができ、など私は、ソートしかし、バブルのために再帰を使用して考えました私はまだそれを実装したいと思っているので、Cと同じくらい快適ではありません。しかし、あなたが示唆を持っているなら、私はそれらを読むことに満足しています。

ありがとうございました!

+4

「インプレース並べ替え」より良い名前... –

+2

'printfのだろう(「%i」は、ARR);'間違っている、あなたは、配列の要素を印刷する必要があります配列自体ではなく 'arr [0]'です。 –

+1

'n-i'は正常ですが、最初のループは' i = 1'で始まります。 'i'が0の場合、内部ループは' for(j = 0; j user3386109

答えて

2

あなたの関数は配列をソートしているようですが(いくつかのバグがありますが)、結果を間違って印刷しているだけです。 printfは配列の出力方法を知らない。代わりに、一度にそれぞれ整数1を印刷するためにループを使用する必要があります。期待通り

for(int i=0; i<5; i++){ 
    printf("%d ", arr[i]); 
} 
printf("\n"); 

これを変更した後、出力は、1 2 3 4 5です。

しかし、コメントに記載されているように、バソルトの実装にはいくつかのバグがあります。たとえば、配列の最後の後にindedexから要素を読み取ろうとします。これは未定義の動作です(つまり、範囲外のj+15になります)。私は、あなたの本をもう一度チェックして、バソソートの正しい実装を得ることをお勧めします。

+0

配列の終わりの後の値が5より大きいことは幸いです。 'int arr [] = {5,4,3,2,1,0};'を試してください。残りのコードは同じです。 – user3386109

+0

私が使用した5は、配列内の要素の数です。配列に6つの要素がある場合は、明らかに6を使用する必要があります。理想的には、要素の数を変数に格納するか、または「#define」を使用して、その場所全体の要素の数を繰り返さないようにします。 – hugomg

+0

要点は、ソートルーチンに未定義の動作があり、配列の最後を超えてアクセスすることです。配列を大きくし、配列が大きいというソートルーチンに指示しないことで、配列の終わりを超えた値を制御し、並べ替えが壊れていることを証明できます。 – user3386109

0

あなたのコードは既に配列をインプレースでソートしていますが、そこにバグがあります。コメントは既にsort関数のバグを強調表示しているので、質問の件名にのみ対処します(Cでの配列のインプレースソート)。それは整数としてarrポインタを印刷しようとしても

結果のプリントアウトが正しくない:

sort.c:10:18: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat] 
    printf("%i", arr); 
      ~~ ^~~ 
1 warning generated. 

しかしにこれを変更:

for (int i = 0; i < 5; i++) 
     printf("%i", arr[i]); 

する問題を修正します出力。

おそらく、あなたの混乱は、配列が実際にC言語のポインタにアクセスするための構文的方法であることに由来します。arrはポインタです。 arr[1]は、*(arr + 1)と同じです(ポインタの内容はarr + 1です)。ポインタの値をsizeofでインクリメントします。したがって、関数にarrを渡すと、既存の配列へのポインタが渡され、その内容を変更して、配列をその場でソートします。

+0

ありがとうございます! arrがポインタであることを知らなかった、すべての助けをありがとう。 – ozymandias1

1

バブルソートコードには1つの問題があり、でなければならない問題があります。これはbecasueある

/* for (int j = 0, hold = 0; j < n-i; j++) { */ // ISSUE here 
for (int j = 0, hold = 0; j < n-i-1; j++) { // j < n-i-1 should be the condition 

、forループの外側のi = 0、すなわち、最初のiterartionのケースを取る:あなたの内側のループには問題があります。今度は、jn(配列の最後のインデックス)より小さい場合、j < n - iは真となります。 values[j]values[j+1]の間では一致しますが、values[j+1]は明らかに配列の範囲外です。これによりundefined behaviorが呼び出され、関数は決定的な結果を出しません。

次の改善点は、外側ループがi = 0 till i < n-1から反復する必要があること、つまり合計要素の1倍未満である可能性があります。あなたは、必要以上に一度だけ介入しています。

第3に、swapの天気を少なくとも1回内側のループに記録するフラグを使用できます。内部ループにスワップがない場合は、配列がすでにソートされていることを意味します。だから、内側のループの各反復の終わりに、スワップが行われたかどうかを確認することができます。スワップが行われなかった場合は、外側のループから抜け出します。これにより、配列がすでにほとんどソートされている場合のパフォーマンスが向上します。あなたはprintfに誤った書式指定子を使用しているため

void bubbleSort(int values[], int n) 
{   
    int swap; // To use as a flag 

    // for (int i = 0; i < n; i++) { 
    for (int i = 0; i < n-1; i++) {     
      swap = 0;  // set swap flag to zero 
      // for (int j = 0, hold = 0; j < n-i; j++) { 
      for (int j = 0, hold = 0; j < n-i-1; j++) { 
        if (values[j] > values[j+1]) { 
          hold = values[j+1]; 
          values[j+1] = values[j]; 
          values[j] = hold; 
          swap = 1;  // swap was done 
        } 
      } 
      if (swap == 0) // If no swap was done 
        break; // Means array already sorted 
    } 
    return; 
} 

そして、あなたの並べ替え機能に関連していないが、他の人が指摘したように、printf("%i", arr);は間違っている、とundefined behaviorを呼び出します。配列を印刷しようとしているようです。そのためにあなたが行うことができます:

// printf("%i", arr); 
for (int i = 0; i < 5; i++) 
    printf("%d ", arr[i];) 
printf("\n"); 
+0

sps、この詳細で徹底的な回答を書く時間を取ってくれてありがとう。本当にあなたの助けと親切に感謝します。 – ozymandias1