c++algorithmsortingmergesort

Merge Sort Function not working when size of vector is not 2^n


I want to preface this question by saying I'm a beginner to c++.

For practice, I tried creating a merge sort function using the elementary knowledge that I have learnt. The code is as follows:

#include <bits/stdc++.h>
using namespace std;

vector<int> mergesort(vector <int> x);
int main(){
    vector<int> tosort={1,9,0};
    tosort=mergesort(tosort);
    for(int  i=0; i<tosort.size(); i++){
        cout<<tosort[i]<<" ";
    }

}
vector<int> mergesort(vector <int> x){
   if (x.size()==1){
       return x ;
   }
   else{
       int vsize=x.size();
       vector<int> halfv1(x.begin(),x.begin()+ceil(vsize / 2));
       vector<int> halfv2(x.begin()+ceil(vsize / 2),x.end());
       
       
       halfv1=mergesort(halfv1);
       halfv2=mergesort(halfv2);
       int counter1=0;
       int counter2=0;
       while(counter1+counter2<vsize){
           if(counter1==ceil(vsize / 2)){
               for(int i=counter1+counter2;i<vsize;i++){
                   x[i]=halfv2[counter2];
                   counter2++;
               }


           }
           if(counter2==floor(vsize / 2)){
               for(int i=counter1+counter2;i<vsize;i++){
                   x[i]=halfv1[counter1];
                   counter1++;
               }

           }
           if(counter1 !=ceil(vsize / 2) && counter2 !=floor(vsize / 2)){
               if(halfv1[counter1 ]<=halfv2[counter2]){
                   x[counter1+counter2]=halfv1[counter1];
                   counter1++;
               }
               else{
                   x[counter1+counter2]=halfv2[counter2];
                   counter2++;
               }
           }
       }
       return x;
   }
}

The code works fine when the size of the vector tosort is 2^n. However, if it isn't then the output is erroneous. For example, in the above example the output is 0 1 0. Please can you help me identify the issue.

I have tried working through the logic line by line and there doesn't seem to be a mistake. I suspect there is an issue with regards to knowledge that I'm not aware of.

Please can you help me out considering I'm a beginner. Also I know there are probably more efficient ways to write the code but I just wanted to practice my algorithm skills with my current knowledge and find my gap in my understanding here.

Thank you very much for your help.


Solution

  • The immediate issue is that the size of halfv2 is not floor(vsize / 2) but vsize - vsize / 2 (or (vsize + 1) / 2)), so you need to change all those comparisons to not access indexes out of bounds. (Note that ceil was only applied to the truncated result of vsize / 2.)

    Consider comparing against the size() of the vectors instead.

    In addition, std::merge provides the functionality you are trying to implement here.