3

マージソートを実装しようとしていますが、機能させることができません。誰かが私の思考(およびコード)の誤りを見つけて指摘できれば、本当にありがたいです。
不要なコードのない主な機能:

int main(int argc, char *argv[]) {
    int n = 0;
    std::cin >> n;
    int num[n];

    for(int i = 0; i < n; i++) {
        std::cin >> num[i];
    }

    sort(num, &num[n - 1], n);

    return(0);
}

マージソート機能:

int *sort(int *s, int *e, int size) {
    if(s == e) {
        return(s);
    }

    int mid = (size + 1) / 2;

    //split array recursively to 1-element arrays

    int *left  = sort(s, (s + mid - 1), mid);
    int *right = sort(s + mid, e, size - mid);

    int *counter = s;

    //merge arrays back together

    while(left < (s + mid - 1) && right <= e) {
        //std::cout << *left << " " << *right << std::endl;

        for(; left < (s + mid - 1) && *left <= *right; left++, counter++) {
            *counter = *left;
        }

        for(; right <= e && *right <= *left; right++, counter++) {
            *counter = *right;
        }
    }

    for(; left < (s + mid - 1); left++, counter++) {
        *counter = *left;
    }
    for(; right <= e; right++, counter++) {
        *counter = *right;
    }

    return(s);
}

input0:
5
4 3 2 1 0
output0:
0 0 0 0 0

input1 :
5
0 1 2 3 4
output1:
1 2 4 4 4

input2:
2
0 1
output2:
1 1

4

2 に答える 2

2

問題はとにあるようです*counter = *left*counter = *rightアルゴリズムの通常の実装では、新しいマージされた配列を作成するために別の配列を使用します。しかし、この場合、あなたはそれをマージしていinplaceます。これを行う*counter = *leftと、その値が失われ、サンプルの実行で表示されるすべてのゼロにつながる可能性があります。

マージする場合、2つの方法でマージできます。の代わりに一時配列を作成して書き込みを続け*counter、両方の配列のすべての要素を使い果たした後、実際の配列に一時配列を再入力するか、マージする配列サイズが事前定義された値。

これらの方法は両方とも http://en.literateprograms.org/Merge_sort_%28C%29で詳細に説明されています。

PS:また、すべての場所で条件left < (s + mid - 1)を変更する必要があると思います。left <=(s + mid -1)

于 2012-04-24T20:11:05.813 に答える
2

元の値を保存せずに(そしてそれを使って何かをして)、ある値を別の値にコピーしているようです。

*counter = *left;
于 2012-04-24T19:24:16.690 に答える