-6

I have written a program for merge sort here and passing the values in the program itself. The output that is being generated is mostly zeroes. Is it because of some error in the while loops or is it because my recursive logic is incorrect?

void merge(int arr[], int s, int e)
{

    int mid = s + (e - s) / 2;

    // the length of the two arrays that we are going to divide the main array in

    int m = mid - s + 1;
    int n = e - mid;

    int* arr1 = new int[m];
    int* arr2 = new int[n];

    //copying values to arr1 and arr2 from the main array arr
    int x = s;
    for (int i = 0; i < m; i++) {
        arr1[i] = arr[x + i];
    }
    for (int j = mid + 1; j < n; j++) {
        arr2[j] = arr[mid + 1 + j];
    }

    int i = 0; // for arr1
    int j = 0; // for arr2
    int k = s; // because this is for the main array

    while (i < m && j < n) {
        if (arr1[i] <= arr2[j]) {
            arr[k] = arr1[i];
            i++;
            k++;
        }

        else {
            arr[k] = arr2[j];
            k++;
            j++;
        }

        while (i < m) {
            arr[k] = arr1[i];
            k++;
            i++;
        }

        while (j < n) {
            arr[k] = arr2[j];
            k++;
            j++;
        }
    }

    delete[] arr1;
    delete[] arr2;
}

//the recursive function
void divide(int arr[], int s, int e)
{

    if (s >= e)
        return;
    int mid = s + (e - s) / 2;
    divide(arr, s, mid);
    divide(arr, mid + 1, e);
    merge(arr, s, e);
}

#include <iostream>
using namespace std;

int main()
{

    int n = 8;
    int arr[8] = { 4, 8, 9, 7, 6, 2, 3, 1 };

    divide(arr, 0, n - 1);

    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }

    return 0;
}

Output for the above code that I am getting is ----> 0 4 0 0 0 0 0 0

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 8
    [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – 463035818_is_not_an_ai Jun 26 '23 at 12:22
  • You should be careful with your indentation, i think the second two while loops shouldn't be inside the first? You should use more descriptive variable names, it'll make your code much easier to read – Alan Birtles Jun 26 '23 at 12:24
  • 3
    Your indexing in the `arr2` copying loop is completely wrong. (The first iteration does `arr2[mid + 1] = arr[mid + 1 + mid + 1];`...) – molbdnilo Jun 26 '23 at 12:36
  • https://godbolt.org/z/nMjEGq3xW – Marek R Jun 26 '23 at 12:49
  • 1
    consider using `std::vector` (and possibly `std::span` if your compiler is new enough) instead of "C" style arrays, passing "C" style arrays is kind of flawed (all size information is lost) and in practice this leads to all kind of bugs. Your source of information seems to be outdated. So where are you learning "C++" from? – Pepijn Kramer Jun 26 '23 at 12:54
  • 2
    Have you tried running your code line-by-line in a debugger while monitoring the control flow and the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Jun 26 '23 at 14:09
  • 2
    Please note that [it is generally expected that you make a debugging attempt yourself before asking for help on Stack Overflow](https://idownvotedbecau.se/nodebugging/). Questions which do not demonstrate any debugging attempt and do not specify what you have learnt in the debugging attempt, are usually not well received. – Andreas Wenzel Jun 26 '23 at 14:10

2 Answers2

1

You are getting seriously confused about your variables.

int m = mid - s + 1;
int n = e - mid;

int* arr1 = new int[m];
int* arr2 = new int[n];

int x = s;
for (int i = 0; i < m; i++) {
    arr1[i] = arr[x + i];
}
for (int j = mid + 1; j < n; j++) {
    arr2[j] = arr[mid + 1 + j];
}

m is the midpoint, and an index into the full array. If is not the number of elements in the first part of the array. That would only be true if s equals zero.

So this is incorrect

int* arr1 = new int[m];

it should be

int* arr1 = new int[m - s];

And this loop is incorrect

int x = s;
for (int i = 0; i < m; i++) {
    arr1[i] = arr[x + i];
}

It should be

for (int i = s; i < m; i++) {
    arr1[i - s] = arr[i];
}

etc. etc. I haven't pointed out all the mistakes but you get the idea. Think about what your variables mean, so that you use them correctly. It also wouldn't hurt to add some comments explaining what they mean, so you or anyone else doesn't get confused.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
john
  • 85,011
  • 4
  • 57
  • 81
  • 1
    rather than comments, I suggest to use meaningful names. `number_of_elemetns_in_the_last_half_of_the_array` needs no comment to explain what it is – 463035818_is_not_an_ai Jun 26 '23 at 12:46
  • @463035818_is_not_an_ai RIP to all `Vim` or `Emacs` users with no IntelliSense `:)` – underloaded_operator Jun 26 '23 at 12:51
  • 1
    @I_throw_but_dont_catch if your text editor can't even do basic code completion you probably should find a better text editor ([vim](http://eclim.org/vim/code_completion.html) does have code completion as does [emacs](https://support.configura.com/hc/en-us/articles/360050804693-Emacs-Auto-complete#:~:text=The%20key%20to%20triggering%20the,can%20be%20used%20as%20well.)) – Alan Birtles Jun 26 '23 at 13:08
  • @AlanBirtles mine didn't (was probably using a very old version, preloaded on the ssh server)... also had to Ctrl X and Ctrl S to go back to the terminal and execute the file, not to mention not knowing how to close `Vim` for a week because by Esc key just disappeared on my Mac. I am sure `Vim` or `Emacs` is useful for more experienced users but for me, it was a struggle `:(` – underloaded_operator Jun 26 '23 at 13:16
  • 1
    @I_throw_but_dont_catch Intellisense isnt the only way to do code completion. That aside, whats the issue with typing long names by hand? It still takes less time than will be spend trying to make sense of code that uses cryptic names only. – 463035818_is_not_an_ai Jun 26 '23 at 13:20
  • @463035818_is_not_an_ai Code is more "typo" prone IMHO... That aside, I agree with what you said, most programmers would prefer lengthy names over "one-letter" variable names – underloaded_operator Jun 26 '23 at 14:09
  • @I_throw_but_dont_catch actually its the opposite. Try to compile code where `number_of_elemetns_in_the_last_half_of_the_array` has any character swapped and you will get a compiler error. Try to compile code where you accidentally swapped a single character in the names `n` and `m` and you will get useless results and a fun debugging session – 463035818_is_not_an_ai Jun 27 '23 at 08:03
  • @463035818_is_not_an_ai Good point – underloaded_operator Jun 27 '23 at 10:21
0

This for loop

for (int j = mid + 1; j < n; j++) {
    arr2[j] = arr[mid + 1 + j];
}

is incorrect. Indices for the dynamically allocated array arr2 start from 0.

So you have to write

for (int j = 0; j < n; j++) {
    arr2[j] = arr[mid + 1 + j];
}

And the second problem is incorrect using braces for the while loops

while (i < m && j < n) {
    if (arr1[i] <= arr2[j]) {
        arr[k] = arr1[i];
        i++;
        k++;
    }

    else {
        arr[k] = arr2[j];
        k++;
        j++;
    }

    while (i < m) {
        arr[k] = arr1[i];
        k++;
        i++;
    }

    while (j < n) {
        arr[k] = arr2[j];
        k++;
        j++;
    }
}

Instead there must be

while (i < m && j < n) {
    if (arr1[i] <= arr2[j]) {
        arr[k] = arr1[i];
        i++;
        k++;
    }

    else {
        arr[k] = arr2[j];
        k++;
        j++;
    }
}

while (i < m) {
    arr[k] = arr1[i];
    k++;
    i++;
}

while (j < n) {
    arr[k] = arr2[j];
    k++;
    j++;
}

That is the last two while loops shall be outside the first while loop.

And you may ignore the incorrect answer of @john that was upvoted even two times.:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • This helped, I got the correct output. Thank you so much for helping @vlad from moscow – Coding_templar Jun 26 '23 at 14:08
  • 1
    @Coding_templar No at all. We, beginners, should help each other. I only wonder that my answer was not down-voted because usually my answers are down-voted as for example that good answer:) https://stackoverflow.com/questions/76531632/how-do-i-print-a-star-pyramid-pattern-using-recursion-without-any-loop-in-c/76531848?noredirect=1#comment134938696_76531848 – Vlad from Moscow Jun 26 '23 at 15:13