简体   繁体   中英

mergesort not working in c++

Is there anything wrong with the usage of the "return" values of the three fuction? The values printed out are garbage values with seemingly random numbers as outputs.I would also like to add that i havent made it recursive because i wanted to check whether this would work or not.

Most all of the mergesort implementation I've seen hardly contain any return values, is that something im doing wrong. If you were to go about a similar type of implementation, how would you do it?

#include <iostream>

using namespace std;

int* goleft(int array[], int size)
{
    int halved=size/2;
    int left[halved];

    for(int i=0;i<halved;i++)
        {
            left[i]=array[i];
        }
    return left;
}

int* goright(int array[],int size)
{
    int halved=size/2;
    int right[size-halved];

    for(int i=halved,j=0;i<size;i++,j++)
        {
            right[j]=array[i];
        }
    return right;
}

int* mergesort(int array[],int size)
{
    int *l,*r;
    l=goleft(array,size);
    r=goright(array,size);
    int merger[size];
    int halved = size/2;
    int i;
    for(i=0;i<halved;i++)
        cout<<l[i]<<endl;

    for(i=0;i<halved;i++)
        cout<<r[i]<<endl;

    int x=0,y=0,k=0;
    while(x+y!=size)
    {
        if(l[x]<r[y])
        {
            merger[k]=l[x];
            x++;k++;
        }
        else if(l[x]>=r[y])
        {
            merger[k]=r[y];
            y++;k++;
        }
    }
    return merger;
}

int main()
{
    int size;
    cin>>size;
    int array[size];

    for(int i=0;i<size;i++)
        cin>>array[i];

    int *merged=mergesort(array,size);

    cout<<"sorted array"<<endl;
    for(int i=0;i<size;i++)
        cout<<merged[i]<<endl;

    return 0;
}

And when we create variables of same name during loops and recursions, are new variable created for every loop iteration or recursion? or do they overwrite the value for the previous variable. for eg when we write

while(true)
{
int i=0;
}

would a new variable be made at every iteration and

genericFunction()
{
 int i = SomeRandomValue
 genericFunction();
}

similarly would a new variable be made at each recursion?

As you thought, the error is in "scopes". To answer to your questions :

while(true)
{
int i=0;
}

The process is :

//iteration N start
create scope
allocate memory for an int variable named 'i' in the current scope
//statements done
delete current scope //deallocate the variables in the current scope
//iteration N end
//iteration N+1 start
/*...*/

So in each iteration it is a different variable. You can test it with this code :

while (true) {
    int i;
    std::cout << &i << std::endl; //displays the memory location of i
    system("PAUSE"); //waiting user input between each iteration
}

In the example with genericfunction, the process is :

//N call to genericFunction
create scope //scope N
    //N+1 call to generic Function
    create scope //scope N+1
        /* statements */
    delete current scope //scope N+1
    // exit of call N+1
delete current scope //scope N
//exit of call N

You can test it with this complete code :

#include <iostream>

void genericFunction(int a)
{
    int i = 0;
    std::cout << "scope " << a << " : " << &i << std::endl;
    if (a < 9) { //to prevent infinite call
        genericFunction(a + 1);
    }
    std::cout << "scope " << a << " : " << &i << std::endl;
}

int main() {
    genericFunction(0);
    system("PAUSE");
    return 0;
}

A generic rule is : when you have { , you create a new scope and select it as current scope, when you have } , you delete the current scope and select the previous scope. Some scopes permits access to previous scopes (for example a WHILE LOOP : in the code int a; while(true) {a++;} , it modifies the value of a in the previous scope), but when a function scope is created you have no access to previous scopes.

Now for your specific issue with mergedsort, it is the declaration of your variable merger inside the function mergesort . To see the process :

/* ... */
int *merged=mergesort(array,size);
//Call to mergesort
    //Creation of scope A
    /* ... */
    int merger[size]; //Allocation of memory for 'merger' in scope A
    /* ... */
    return merger; //Affect the location of 'merger' to location pointed by 'merged' in previous scope
    //Deletion of scope A (including deallocation of 'merger')
// Now 'merged' points to location of 'merger' which is a deallocated variable :
//no guarantees of the data stored at this location

So it is why there is a problem in your code. One way to correct it is by allocate manually some space for your variable : variables allocated manually have to be deallocated manually, so they will not be deallocated when destroying a scope. Actually the implementation inside the function is using the c++ keyword new : int *merger = new int[size]; . By replacing this declaration your code will be running : but be careful : here's an other rule, if you're using somewhere the keyword new you have to use delete somewhere else : manual allocation have to be followed by manual deallocation. So at the end of your main function, you have to add delete[] merged; . In this way there's no trouble ;) .

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