简体   繁体   中英

the code of merge_sort doesn`t sort properly

i code the merge sort as below but it doesn't sort the Array. and i cant find the source of the problem.

void print_arr(int Arr[], int size)

{

    int i;

    for (i = 0;i < size;i++)
        printf(" %d ", Arr[i]);
}

///////////////////////////////////////////

void merge(int Arr[], int left, int mid, int right)

{

    int i = 0, j = 0, k = left;
    int n_l = (mid - left + 1);
    int n_r = (right - mid);
    int* Arr_l = (int*)calloc(n_l , sizeof(int));
    int* Arr_r = (int*)calloc(n_r , sizeof(int));
    if (Arr_l == NULL)
        return;
    if (Arr_r == NULL)
        return;

    for (i = 0;i < n_l;i++)
        Arr_l[i] = Arr[i];

    for (j = 0;j < n_r;j++)
        Arr_r[j] = Arr[mid + 1 + j];

    while (i < n_l && j < n_r)
    {
        if (Arr_l[i] <= Arr_r[j])
        {
            Arr[k] = Arr_l[i];
            i++;
            k++;
        }
        else
        {
            Arr[k] = Arr_r[j];
            j++;
            k++;
        }
    }

    while (i < n_l)
    {
        Arr[k] = Arr_l[i];
        i++;
        k++;
    }

    while (j < n_r)
    {
        Arr[k] = Arr_r[j];
        j++;
        k++;
    }
    free(Arr_l);
    free(Arr_r);
}
////////////////////////////////////////////////////////////////////

void merge_sort_inc(int Arr[], int left, int right)
{

    int mid = (int)((left + (right - 1)) / 2);
    if (left < right)
    {   
        merge_sort_inc(Arr, left, mid);
        merge_sort_inc(Arr, mid + 1, right - 1);
        merge(Arr, left, mid, right);
    }

}

////////////////////////////////////////////////////////////////

int main()

{

    int i;
    time_t t;
    srand((unsigned)time(&t));
    int Array[10];
    int size = sizeof(Array) / sizeof(int);
    for (i = 0;i < size;i++)
        Array[i] = rand() / 100;
    printf(" The unsorted Arrar is : \n\n");
    print_arr(Array, size);

    printf("\n\n The sorted Array is : \n ");

    merge_sort_inc(Array, 0, size);

    print_arr(Array, size);
    return 0;
}
int i = 0, j = 0, k = left;

you should reset the value of i , j before while loop

    i = 0; j = 0; k = left;  
    while (i < n_l && j < n_r)
    {...}

Then:

for (i = 0;i < n_l;i++)
        Arr_l[i] = Arr[i];

change to

for (i = 0;i < n_l;i++)
        Arr_l[i] = Arr[left+i];

Finally, the merge_sort_inc function should change to:

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

Then in main function, when you call merge_sort_inc function in main:

merge_sort_inc(Array, 0, size-1); // change size to size-1

OT, your part of code below is not wrong:

    while (i < n_l)
    {
        Arr[k] = Arr_l[i];
        i++;
        k++;
    }

    while (j < n_r)
    {
        Arr[k] = Arr_r[j];
        j++;
        k++;
    }

But you can bring k++ to the end of condition to limit one line of code as:

    while (i < n_l)
    {
        Arr[k] = Arr_l[i];
        i++;
    }

    while (j < n_r)
    {
        Arr[k] = Arr_r[j];
        j++;
    }
    k++;

The complete code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void print_arr(int Arr[], int size)
{
    int i;

    for (i = 0;i < size;i++)
        printf(" %d ", Arr[i]);
}

void merge(int Arr[], int left, int mid, int right)

{
    int i, j, k; 
    int n_l = (mid - left + 1);
    int n_r = (right - mid);
    int* Arr_l = calloc(n_l , sizeof(int));
    int* Arr_r = calloc(n_r , sizeof(int));
    if (Arr_l == NULL)
        return;
    if (Arr_r == NULL)
        return;

    for (i = 0;i < n_l;i++)
        Arr_l[i] = Arr[left+i];

    for (j = 0;j < n_r;j++)
        Arr_r[j] = Arr[mid + 1 + j];

    i = 0; j = 0; k = left;

    while (i < n_l && j < n_r)
    {
        if (Arr_l[i] <= Arr_r[j])
        {
            Arr[k] = Arr_l[i];
            i++;
        }
        else
        {
            Arr[k] = Arr_r[j];
            j++;
        }
        k++;
    }

    while (i < n_l)
    {
        Arr[k] = Arr_l[i];
        i++;
        k++;
    }

    while (j < n_r)
    {
        Arr[k] = Arr_r[j];
        j++;
        k++;
    }
    free(Arr_l);
    free(Arr_r);
} 

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


int main()
{

    int i;
    time_t t;
    srand((unsigned)time(&t));
    int Array[10];
    int size = sizeof(Array) / sizeof(int);
    for (i = 0;i < size;i++)
        Array[i] = rand() % 100; // should use % instead of / to have smaller value to see easily
    printf(" The unsorted Arrar is : \n\n");
    print_arr(Array, size);

    printf("\n\n The sorted Array is : \n ");

    merge_sort_inc(Array, 0, size-1);

    print_arr(Array, size);
    return 0;
}

The output of test:

 The unsorted Arrar is :                                                                                                

 60  32  71  35  93  91  29  80  78  47                                                                                 

 The sorted Array is :                                                                                                  
  29  32  35  47  60  71  78  80  91  93 

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