简体   繁体   中英

Error with Mergesort implementation in C++

I am learning to implement a mergesort algorithm for use to count inversions. Here is my current implementation of mergesort. However it is not working as it does not return a sorted array. Will anyone be able to tell me what is being done wrongly in this code which I have written? It should sort the array v which is input into the function.

void mergeCountInversion(vector<int> v, int l, int r)
{
    if (l >= r)
    {
        return;
    }

    int m = (l + r)/2;  

    //call merge sort to return two sorted arrays
    mergeCountInversion(v, l, m);
    mergeCountInversion(v, m+1, r);

    int left = l;
    int right = m+1;
    std::vector<int> vtemp ;

    //merge and sort the two sorted array, storing the sorted array in vtemp
    for (int k = l; k <= r; ++k){
        if (left >= m+1)
        {
            vtemp.push_back(v[right]);
            right++;
        }
        else if (right > r)
        {
            vtemp.push_back(v[left]);
            left++;
        }
        else
        {
            if (v[left] <= v[right])
            {
                vtemp.push_back(v[left]);
                left++;
            }
            else{
                vtemp.push_back(v[right]);
                right++;
                count += m + 1 - left;
            }
        }
    }

    //replace v with the sorted array vtemp
    for (int i = 0; i < vtemp.size(); ++i)
    {
        v[l+i] = vtemp[i];
    }
}

You defined

void mergeCountInversion(vector<int> v, int l, int r)

then you first call mergeCountInversion recursively, and modify v after the calls returned.

The problem is that the changes to v made in the recursive calls will never be seen, because v is passed by value .

Try to pass v by reference :

void mergeCountInversion(vector<int>& v, int l, int r)

such that all calls work on the same copy of v .

There are several issues in your code.

You are passing the vector by value, but you should pass it by refernce.

If you declare the function as void You can't return 0; , just return; .

When you create vtemp you should know exactly its size: r - l. So you can reserve memory for it and you don't need to push_back.

You have to pass count to the function too.

Your function can be:

void mergeCountInversion(vector<int> & v, int l, int r, int & count) {
    if (l >= r) return;

    int m = (l + r)/2;  

    //call merge sort to return two sorted arrays
    mergeCountInversion(v, l, m, count);
    mergeCountInversion(v, m+1, r, count);

    int left = l;
    int right = m+1;
    std::vector<int> vtemp(r-l);

    //merge and sort the two sorted array, storing the sorted array in vtemp
    for (int k = l; k <= r; ++k) {
        if (left >= m+1) {
            vtemp[k] = v[right];
            right++;
        }
        else if (right > r) {
            vtemp[k] =  v[left];
            left++;
        }
        else {
            if (v[left] <= v[right]) {
                vtemp[k] = v[left];
                left++;
            }
            else {
                vtemp[k] = v[right];
                right++;
                count += m + 1 - left;
            }
       }
    }

    //replace v with the sorted array vtemp
    for (int i = 0; i < vtemp.size(); ++i)
    v[l+i] = vtemp[i];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM