Search code examples
arrayscsortingmergesortfunction-definition

Merge sort in C returns a list containing duplicates of the same 3-4 numbers. Other numbers are missing from sorted list


I'm trying to implement a basic merge sort program in C. However, I keep getting multiple instances of the same numbers in a row, where as other numbers are completely skipped. I used the following functions and main

void merge_sort(int *arr, int left, int right){
    if (left<right){
        int mid = left + (right-left)/2;

        merge_sort(arr, left, mid);
        merge_sort(arr, mid+1, right);

        merge(arr, left, mid, right);
    }
}

void merge(int *arr, int left, int mid, int right){
    int lenght1 = mid - left + 1;
    int lenght2 = right - mid;
    int left_arr[lenght1];
    int right_arr[lenght2];

    int i, j;
    for (i=0; i<lenght1; i++)
        left_arr[i] = arr[left+i];
    for (j=0; j<lenght2; j++)
         right_arr[j] = arr[mid + 1 + j];

    i=0;
    j=0;
    int k = left;
    while(i<lenght1 && j<lenght2){
        if (left_arr[i]<=right_arr[j]){ 
            arr[k] = left_arr[i]; 
            i++;
        }
        else{
            arr[k] = right_arr[j]; 
            j++;
        }
        k++;
    }
    while (j<lenght2){
        arr[k] = right_arr[j];
        j++;
        k++;
    }
}

void print_array(int array[], int length){
for (int i=0; i<length; i++)
    printf("%d ", array[i]);   
}

//MAIN FILE
#include <stdio.h> 
#include <stdlib.h>
#include "sorting.h"

#define ARR_LENGHT 8

int main(int argc, char *argv[]){
    int arr[ARR_LENGHT];
    if (argc!=ARR_LENGHT+1)
        printf("Too many or too few arguments passed.");
    else{
        for (int i=1; i<=ARR_LENGHT; i++)
            arr[i-1]=strtod(argv[i], NULL);
        merge_sort(arr, 0, ARR_LENGHT-1);
        print_array(arr, ARR_LENGHT);
    }
    return 0;
}

example of input and output: input: 6 5 4 3 2 1 8 9 output: 1 1 3 3 3 3 8 9


Solution

  • For starters it is unclear why you are using the standard function strtod that is designed to parse double values instead of for example strtol or even atoi.

    As for the function definitions then apart from this while loop within the function merge

    while (j<lenght2){
        arr[k] = right_arr[j];
        j++;
        k++;
    }
    

    you also need to add one more while loop

    while (i<lenght1){
        arr[k] = left_arr[i];
        i++;
        k++;
    }
    

    That is you will have

    while (j<lenght2){
        arr[k] = right_arr[j];
        j++;
        k++;
    }
    
    while (i<lenght1){
        arr[k] = left_arr[i];
        i++;
        k++;
    }
    

    The order of the while loops is unimportant.

    Also the function merge should be declared before the function merge_sort.