2016-09-17 4 views
-2

私はアルゴリズムに慣れていません。マージソートの作業をしようとしていますが、正しい出力が得られません。コンパイルエラーはありませんが、ソートされた配列として出力にランダムな値が表示され、どこかに欠陥があると思います。あなたのmerge機能でC++でマージソートを実装できません

void merge_sort(int[], int, int); 
void merge(int[], int, int, int); 
void printarray(int[], int); 

int main() { 
    int Arr[100], num_of_elements; 
    cout << "Enter the number of elements (max 100): "; 
    cin >> num_of_elements; 
    cout << "Enter array elements: \n"; 
    for (int i = 0;i < num_of_elements;++i) 
     cin >> Arr[i]; 
    merge_sort(Arr, 0, num_of_elements - 1); 
    cout << "\nAfter Sorting (by Merge Sort):\n"; 
    printarray(Arr, num_of_elements); 
    cout << endl; 
    return 0; 
} 

void merge_sort(int arr[], int left, int right) { 
    if (left < right) { 
     int mid = (left + right)/2; 
     merge_sort(arr, left, mid); 
     merge_sort(arr, mid + 1, right); 
     merge(arr, left, mid, right); 
    } 
} 

void merge(int arr[], int left, int mid, int right) { 
    int i, j, k; 

    /* Calculate the lengths of the subarrays and copy the elements into them */ 
    int lenght_left = mid - left + 1; 
    int length_right = right - mid; 
    int *leftarray = new int[lenght_left]; 
    int *rightarray = new int[length_right]; 
    for (i = 0;i < lenght_left;++i) 
     leftarray[i] = arr[left + i]; 
    for (j = 0;j < length_right;++j) 
     rightarray[j] = arr[mid + 1 + j]; 

    /* Reordering the elements in the original array */ 
    for (k = left, i = 0, j = 0;k <= right;++k) { 
     if (leftarray[i] <= rightarray[j]) 
      arr[k] = leftarray[i++]; 
     else 
      arr[k] = rightarray[j++]; 
    } 

    /* Copy remaining elements into the array */ 
    while (i < lenght_left) 
     arr[k] = leftarray[i++]; 
    while (j < length_right) 
     arr[k] = rightarray[j++]; 
    delete[](leftarray); 
    delete[](rightarray); 
} 

void printarray(int arr[], int num) { 
    cout << "Displaying Elements in array: \n"; 
    for (int i = 0;i < num;i++) 
     cout << arr[i] << " "; 
} 
+0

を[、最小完全、かつ検証例]を作成する場合(http://stackoverflow.com/help/mcve)ことが重要です実際にそれを*完全なものにして、あなたが持っている機能がどのように使われているか、それらに渡される入力、そして予想される出力と実際の出力を示します。また、[良い質問をする方法について読む](http://stackoverflow.com/help/how-to-ask)をご覧ください。 –

+0

このような問題を解決する適切なツールは、デバッガです。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。最低限、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、その問題を再現するためのデバッガ。 –

+0

'ソートされた配列として出力にランダムな値を表示することはどういう意味ですか? '配列がまったくソートされない、部分的にソートされる、またはガベージデータでいっぱいになることを意味しますか?最後の場合は、どこかにメモリの問題があります(=>デバッガ)。マージソート関数の呼び出し(配列の初期化と関数への渡し方を含む)も表示できますか? – rbaleksandar

答えて

0

:あなたはループを制御するために使用している条件が適切ではない

/* Reordering the elements in the original array */ 
for (k = left, i = 0, j = 0; k <= right; ++k) { 
//       ^^^^^^^^^^^ 
// It should be i < lenght_left && j < length_right 
    if (leftarray[i] <= rightarray[j]) 
     arr[k] = leftarray[i++]; 
    else 
     arr[k] = rightarray[j++]; 
} 

、条件があなたのleftarrayrightarrayに関してである必要があり、それがあるべき、といういずれかの配列が最後まで到達したら、条件をi < lenght_left && j < length_rightに変更します。

と同じ機能で、残りの要素をコピーするとき:

/* Copy remaining elements into the array */ 
while (i < lenght_left) 
    arr[k] = leftarray[i++]; 
//  ^^^ 
while (j < length_right) 
    arr[k] = rightarray[j++]; 
//  ^^^ 

をここで、あなたは、kをインクリメントk++にそれらを変更するのを忘れました。

0

ミスのカップルは、あなたが作っているがあります。

  1. をあなたが

    すなわち代わりにマージしているときに、配列の長さにわたって行っていないことを確認する必要があります。

    for (k = left, i = 0, j = 0;k <= right;++k) 
    

    あなたは持っている必要があります。

    for (k = left, i = 0, j = 0;k <= right && i <lenght_left && j<length_right;++k) 
    
  2. 残っている要素を追加するときは、配列カウンタを大きくすることを忘れないでください。 すなわち:

    while (i < lenght_left) 
        arr[k] = leftarray[i++]; 
    while (j < length_right) 
        arr[k] = rightarray[j++]; 
    

    あなたは持っている必要があります。

    while (i < lenght_left) 
        arr[k++] = leftarray[i++]; 
    while (j < length_right) 
        arr[k++] = rightarray[j++]; 
    
+0

ありがとう!出来た。私はちょうど** i **と** j **をそれぞれの長さよりも小さくする必要がないのをなぜチェックしないのだろうと思っています。 ** k **のループは、merge()メソッドのサブ配列にある要素の数だけ実行する必要がありますか? –

+0

あなたはそれに答えることができますか? –

+0

ケースの左側の部分を考えてみましょう:10 11 12と右側の部分は1 2 3です。次に起こることは、arrに10 11 12を追加し、左の配列のオフセットをチェックします範囲の。 – JukesOnYou

関連する問題