Quick Sort program stopped working - c++

I was trying to solve the quick sort - 2 challenge on hackerrank. It said that we had to repeatedly call partition till the entire array was sorted. My program works for some test cases but for some it crashes, "Quick Sort - 2.exe has stopped working". I couldn't find the reason as to why it's happening.
The first element of the array/sub-array was to be taken as pivot element each time.
#include <iostream>
#include <conio.h>
using namespace std;
void swap(int arr[], int a, int b)
{
int c = arr[a];
arr[a] = arr[b];
arr[b] = c;
}
void qsort(int arr[], int m, int n) //m - lower limit, n - upper limit
{
if (n - m == 1)
{
return;
}
int p = arr[m], i, j, t; //p - pivot element, t - temporary
//partition
for (int i = m+1; i < n; i++)
{
j = i;
if (arr[j] < p)
{
t = arr[j];
while (arr[j] != p)
{
arr[j] = arr[j-1];
j--;
}
arr[j] = t; //pivot is at j and j+1
}
}
//check if sorted
int f = 1;
while (arr[f] > arr[f-1])
{
if (f == n-1)
{
f = -1;
break;
}
f++;
}
if (f == -1)
{
cout << "Sub Array Sorted\n";
}
else
{
if (p == arr[m]) //pivot is the smallest in sub array
{
qsort(arr, m+1, n); //sort right sub array
}
else
{
qsort(arr, m, j+1); //sort left sub array
qsort(arr, j+1, n); //sort right sub array
}
}
}
int main()
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
qsort(arr, 0, n);
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
return 0;
}

You have an index out of range problem.
This will not give you the solution, but it may help you to find the reason why your program fails.
I have modified your program so it uses a vector of int rather than a raw array of int, and when you run this program you get an index out of range exception.
The sequence 4 3 7 1 6 4 that triggers the problem is hardcoded, so you don't need to type it each time.
#include <iostream>
#include <vector>
using namespace std;
void swap(vector<int> & arr, int a, int b)
{
int c = arr[a];
arr[a] = arr[b];
arr[b] = c;
}
void qsort(vector<int> & arr, int m, int n) //m - lower limit, n - upper limit
{
if (n - m == 1)
{
return;
}
int p = arr[m], j, t; //p - pivot element, t - temporary
//partition
for (int i = m + 1; i < n; i++)
{
j = i;
if (arr[j] < p)
{
t = arr[j];
while (arr[j] != p)
{
arr[j] = arr[j - 1];
j--;
}
arr[j] = t; //pivot is at j and j+1
}
}
//check if sorted
int f = 1;
while (arr[f] > arr[f - 1])
{
if (f == n - 1)
{
f = -1;
break;
}
f++;
}
if (f == -1)
{
cout << "Sub Array Sorted\n";
}
else
{
if (p == arr[m]) //pivot is the smallest in sub array
{
qsort(arr, m + 1, n); //sort right sub array
}
else
{
qsort(arr, m, j + 1); //sort left sub array
qsort(arr, j + 1, n); //sort right sub array
}
}
}
int main()
{
vector<int> arr = { 4,3,7,1,6,4 };
qsort(arr, 0, arr.size());
for (unsigned int i = 0; i < arr.size(); i++)
{
cout << arr[i] << " ";
}
return 0;
}

First of all, what you made is not quick sort, but some combination of divide-ans-conquer partitioning and insert sort.
Canonical quicksort goes from from lower (p) and upper (q) bounds of array, skipping elements arr[p]m respectively. Then it swaps arr[p] with arr[q], increments/decrements and checks if p>=q. Rinse and repeat until p>=q. Then make calls on sub-partitions. This way p or q holds pivot position and subcalls are obvious.
But you are doing it different way: you insert elements from right side of subarray to left side. Such thing can produce O(N^2) time complexity for one iteration. Consider 1,0,1,0,1,0,1,0,1,0,1,0,... sequence, for example. This can increase worst case complexity over O(N^2).
Out of time complexity... The problem in your function lies in assumption that j holds pivot location in subcalls:
qsort(arr, m, j+1); //sort left sub array
qsort(arr, j+1, n); //sort right sub array
Actually, j is set again and again equal to i in your main for loop. If last element is equal or greater than pivot, you end up with j=n-1, the you call qsort(arr, n, n) and first lines check is passed (sic!), because n-n != 1.
To fix this you should do two things:
1) find pivot location directly after rearrange:
for (int i = m; i < n; i++)
if (p == arr[i])
{
j = i;
break;
}
or initialize it in different variable, update after this line:
arr[j] = t; //pivot is at j and j+1
and update recursive calls to use new variable instead of j
2) make a more bulletproof check in the beginning of your function:
if (n - m <= 1)
the latter will be enough to get some result, but it will be much less effective than your current idea, falling down to probably O(N^3) in worst case.

Related

Juggling algorithm regarding Right Array rotation

Recently I learnt about the array rotation in linear time using Juggling algorithm. Here is the snippet regarding the left rotation of the array.
void ArrayRotate (int A[], int n, int k)
{
int d=-1,i,temp,j;
for(i=0;i<gcd(n,k);i++)
{
j=i;
temp=A[i];
while(1)
{
d=(j+k)%n;
if(d==i)
break;
A[j]=A[d];
j=d;
}
A[j]=temp;
}
}
but now I am stuck as how to use this Juggling algorithm to rotate the array in the Right Direction.
1,2,3,4,5 (given array)
5,1,2,3,4 (after 1 right rotation)
(I had solved this question using the brute force method and reversal method.)
As already mentioned, you should use std::rotate if you are allowed to.
Your implementation has a bug. Here is a fixed implementation.
void ArrayRotate(int A[], int n, int k) {
int d = -1, i, temp, j;
int g = gcd(n, k);
for (i = 0; i < g; ++i) {
j = i;
temp = A[i];
while (true) {
d = (j + k) % n;
if (d == i) {
break;
}
A[j] = A[d];
j = d;
}
A[j] = temp;
}
}
Also note that I took out gcd calculation out of loop condition. It does not technically affect complexity, but it's enough to compute the gcd only once.
To rotate the array k times to the right, just rotate it n - k times to the left.
void ArrayRotateRight(int A[], int n, int k) {
ArrayRotate(A, n, n - k);
}
Or change the 8th line to be d = (j - k + n) % n;
Not sure if you're doing this as an intellectual exercise, or for production code, but for production code use the STL rotate algorithm:
#include<iostream>
#include<algorithm>
using namespace std;
void display(int* a, int length)
{
for (int i = 0; i < length; ++i)
cout << a[i] << " ";
cout << endl;
}
int main()
{
const int len = 5;
int arr[] = { 1,2,3,4,5 };
display(arr, len);
rotate(arr, arr + 1, arr + len); // arr + x means left by x
display(arr, len);
rotate(arr, arr + len - 1, arr + len); // arr + len - x means right by x
display(arr, len);
}

Getting different output on each execution

I tried to implement number of inversions in an array, using merge sort.
Every time I execute this code, I get different value of the number of inversions. I am not able to figure out the reason for this. Please have a look at the code and tell me the mistake.
#include<stdio.h>
#include<iostream>
using namespace std;
int count =0;
void merge(int A[],int start,int mid,int end)
{
int size1 = mid-start+1;
int size2 = end-(mid+1)+1;
int P[size1];
int Q[size2];
for(int i=0;i<size1;i++)
P[i]=A[start+i];
for(int j=0;j<size2;j++)
Q[j]=A[mid+j+1];
int k = 0;
int l = 0;
int i =0;
while(k<mid && l<end)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count++;
}
else
{
A[i] = P[k];
k++; i++;
}
}
}
void inversions(int A[],int start,int end)
{
if(start!=end)
{
int mid = (start+end)/2;
inversions(A,start,mid);
inversions(A,mid+1,end);
merge(A,start,mid,end);
}
}
int main()
{
int arr[] = {4,3,1,2,7,5,8};
int n = (sizeof(arr) / sizeof(int));
inversions(arr,0,n-1);
cout<<"The number of inversions is:: "<<count<<endl;
return 0;
}
int k = 0;
int l = 0;
int i =0;
while(k<mid && l<end)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count++;
}
else
{
A[i] = P[k];
k++; i++;
}
}
Few mistakes here, i starts from start and not 0. k must loop from 0 till size1 and not till mid. Similarly, l must loop from 0 till size2 and not till end. You are incrementing count by 1 when P[k] > Q[l] but this is incorrect. Notice that all the elements in array P following the element P[k] are greater than Q[l]. Hence they also will form an inverted pair. So you should increment count by size1-k.
Also, the merge procedure should not only count the inversions but also merge the two sorted sequences P and Q into A. The first while loop while(k<size1 && l<size2) will break when either k equals size1 or when l equals size2. Therefore you must make sure to copy the rest of the other sequence as it is back into A.
I have made the appropriate changes in merge and pasted it below.
void merge(int A[],int start,int mid,int end)
{
int size1 = mid-start+1;
int size2 = end-(mid+1)+1;
int P[size1];
int Q[size2];
for(int i=0;i<size1;i++)
P[i]=A[start+i];
for(int j=0;j<size2;j++)
Q[j]=A[mid+j+1];
int k = 0;
int l = 0;
int i = start;
while(k<size1 && l<size2)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count += size1-k;
}
else
{
A[i] = P[k];
k++; i++;
}
}
while (k < size1)
{
A[i] = P[k];
++i, ++k;
}
while (l < size2)
{
A[i] = Q[l];
++i, ++l;
}
}
int P[size1];
int Q[size2];
VLA (Variable length arrays) are not supported by C++. size1 and size2 are unknown during compile time. So, each time they get a different value and hence the difference in output.
Use std::vector instead
std::vector<int> P(size1, 0); //initialize with size1 size
std::vector<int> Q(size2, 0); //initialize with size2 size

Kth smallest element- can't create array more than the size of k

I have implemented an algorithm that solves the problem of finding the kth smallest element in an unsorted array. I have used the heap structure, and optimized the code by relying on this formula,
k1 = n - k + 1
k1 being the k1th largest element, so I go for the smaller of k and k1.
Still, I couldn't pass the time limit error on an online judge. I don't know if there will be any further more better complexity having in mind that I have to create an array no more than the size of k; maybe less than k possible? Or there is another way to solve this problem other than using the heap structure.
1 <= k <= n <= 105
The code:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
void minHeapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
if (l < n && arr[l] < arr[largest])
largest = l;
if (r < n && arr[r] < arr[largest])
largest = r;
if (largest != i) {
swap(arr[i], arr[largest]);
minHeapify(arr, n, largest);
}
}
void maxHeapify(int arr[], int n, int i)
{
int smallest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
if (l < n && arr[l] > arr[smallest])
smallest = l;
if (r < n && arr[r] > arr[smallest])
smallest = r;
if (smallest != i) {
swap(arr[i], arr[smallest]);
maxHeapify(arr, n, smallest);
}
}
void buildMinHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
minHeapify(a, n, i);
}
void buildMaxHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
maxHeapify(a, n, i);
}
int kthsmallest(int minHeap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> minHeap[i];
buildMaxHeap(minHeap, k);
for (i = k; i < n; i++)
{
cin >> temp;
if (temp < minHeap[0])
{
minHeap[0] = temp;
maxHeapify(minHeap, k, 0);
}
}
return minHeap[0];
}
int kthlargest(int minHeap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> minHeap[i];
buildMinHeap(minHeap, k);
for (i = k; i < n; i++)
{
cin >> temp;
if (temp > minHeap[0])
{
minHeap[0] = temp;
minHeapify(minHeap, k, 0);
}
}
return minHeap[0];
}
int main() {//kth smallest element
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, k1;
cin >> n >> k;
k1 = n - k + 1;//kth smallest element is the same as k1th largest element
if (k < k1) {
int *minHeap = new int[k];
cout << kthsmallest(minHeap, k, n);
}
else {
int *minHeap = new int[k1];
cout << kthlargest(minHeap, k1, n);
}
return 0;
}
Please if you could help finding a better time complexity?
Problem:
Find the kth largest element of an array
Memory limit: 256 MBs
Time limit: 1 s
Input: input.txt
Output: output.txt
Task:
You are given an array of n integers and a natural k.
You have to find the kth largest element of the array.
You can't create array consisting of more than k elements.
Input:
The first line contains a natural n (1 ≤ n≤105) – the
quantity of elements of the array, and the natural k.
The second line contains n numbers – the elements of the array.
Output:
The kth largest element of the array.
Example:
Input | Output
-------------+-----------
6 2 | 7
7 4 6 3 9 1 |
The time complexity is optimal, but you can make your code a tiny bit more efficient:
Don't use recursion, but an iterative solution
Don't use swap, but keep the original value in memory while copying child values to their parents and only store the initial value once you have reached the appropriate slot.
Don't perform twice 2 * i: the other child node is just the next one.
Let the heapify functions take an extra argument, which can be either the current value at index i, or the replacement value for it. This saves one assignment.
Here is how that would look for two heapify functions:
void minHeapify(int arr[], int n, int i, int key) { // add key as parameter
while (true) { // iterative
int child = 2 * i + 1; // do this only for left child, and limit number of variables
if (child+1 < n && arr[child] > arr[child+1]) // get child with least value
child++; // the right child is just one index further
if (child >= n || key <= arr[child]) break;
arr[i] = arr[child]; // don't swap, just copy child value to parent
i = child; // move down
}
arr[i] = key; // finally put the original value in the correct place
}
void maxHeapify(int arr[], int n, int i, int key) { // add key as parameter
while (true) { // iterative
int child = 2 * i + 1; // do this only for left child, and limit number of variables
if (child+1 < n && arr[child] < arr[child+1]) // get child with greatest value
child++; // the right child is just one index further
if (child >= n || key >= arr[child]) break;
arr[i] = arr[child]; // don't swap, just copy child value to parent
i = child; // move down
}
arr[i] = key; // finally put the original value in the correct place
}
void buildMinHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
minHeapify(a, n, i, a[i]); // pass a[i] also
}
void buildMaxHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
maxHeapify(a, n, i, a[i]); // pass a[i] also
}
int kthsmallest(int heap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> heap[i];
buildMaxHeap(heap, k);
for (i = k; i < n; i++) {
cin >> temp;
if (temp < heap[0])
maxHeapify(heap, k, 0, temp); // pass temp
}
return heap[0];
}
int kthlargest(int heap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> heap[i];
buildMinHeap(heap, k);
for (i = k; i < n; i++) {
cin >> temp;
if (temp > heap[0])
minHeapify(heap, k, 0, temp); // pass temp
}
return heap[0];
}
In main function you could make a special case for when k == 1 or k == n, so no heap is needed, just min() or max().
One strange thing is that the challenge you link to speaks of "kth largest" while you speak of "kth smallest". Maybe you mixed up.
So here is the code when the job is to return the kth smallest. But please check the challenge whether you should not have done it for kth largest:
int main() {//kth smallest element
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, k1;
cin >> n >> k;
k1 = n - k + 1;//kth smallest element is the same as k1th largest element
if (k == 1) {
int curr, next;
cin >> curr;
for (int i = 1; i < n; i++) {
cin >> next;
curr = min(curr, next);
}
cout << curr;
} else if (k1 == 1) {
int curr, next;
cin >> curr;
for (int i = 1; i < n; i++) {
cin >> next;
curr = max(curr, next);
}
cout << curr;
} else if (k < k1) {
int *heap = new int[k];
cout << kthsmallest(heap, k, n);
} else {
int *heap = new int[k1];
cout << kthlargest(heap, k1, n);
}
return 0;
}
You're making the assumption that using a smaller heap is always the best choice. You might want to re-think that.
For example, imagine you want to select the 96th smallest number from a list of 100. If you use a heap of size 96, then you'll do:
Build a heap with 96 items. buildHeap is O(n), and in this case n is 96.
Do up to 4 insertions into a heap of 96 items. That'll be 4*log(96).
If you use a heap of size 4, then you'll do:
Build a heap with 4 items.
Do up to 96 insertions into a heap of 4 items. That'll be 96*log(4).
The first option is 96 + 4*log(96). The base-2 log of 96 is about 6.58. So the insertions will cost 26.32, for a total of 122.32.
The second option, with the smaller heap, is 4 + 96*log(4). log(4) is 2, so you end up with 4 + 196, or a total of 196.
The smaller heap is a big loser here.
In general, you want to use the larger heap when (k + (n-k)*log(k)) < ((n-k) + k*log(n-k)).
Also:
The real-world running time of the heap selection algorithm is kind of sensitive to the order in which items are presented. For example, if you're looking for 1000th smallest number in an array of 100,000, it's going to run much faster if the array is in ascending order than if it's in descending order. The reason?
Because in the ascending case, you build your initial heap with the first 1,000 items and then you never have to modify the heap again because there is none of the following items are smaller than the largest item on the heap.
But if the array is in descending order, then every item you look at will be smaller than the largest item on the heap, which means you'd be doing a heap insertion for all 99,000 remaining items.
Imagine how your code would perform if one of the test cases is a large array in descending order.
Unless you've already proven that your way of selecting which heap size to use is clearly better, you might want to consider just going with "select kth smallest," using a maxheap of size k, regardless.

What is wrong in this implementation of merge sort?

I know that there are many implementations of merge sort but this is one which I have read in the book "Introduction to algorithms". The following code is an implementation of merge sort which is not working correctly:
#include <iostream>
using namespace std;
void merge(int*a, int p, int q, int r) { //function to merge two arrays
int n1 = (q - p); // size of first sub array
int n2 = (r - q); // size of second subarray
int c[n1], d[n2];
for (int i = 0; i <= n1; i++) {
c[i] = a[p + i];
}
for (int j = 0; j <= n2; j++) {
d[j] = a[q + j];
}
int i = 0, j = 0;
for (int k = p; k < r; k++) { // merging two arrays in ascending order
if (c[i] <= d[j]) {
a[k++] = c[i++];
} else {
a[k++] = d[j++];
}
}
}
void merge_sort(int*a, int s, int e) {
if (s < e) {
int mid = (s + e) / 2;
merge_sort(a, s, mid);
merge_sort(a, mid + 1, e);
merge(a, s, mid, e);
}
}
int main() {
int a[7] { 10, 2, 6, 8, 9, 10, 15 };
merge_sort(a, 0, 6);
for (auto i : a)
cout << i << endl;
}
This code is not working correctly. What's wrong in this code? How can it be fixed?
First of all you should be correctly set for the size of the array.
void merge(int*a, int p, int q, int r) { //function to merge two arrays
/* If i am not wrong , p is the starting index of the first sub array
q is the ending index of it also q+1 is the starting index of second
sub array and r is the end of it */
/* size of the sub array would be (q-p+1) think about it*/
int n1 = (q - p); // size of first sub array
/* This is right n2 = (r-(q+1)+1)*/
int n2 = (r - q); // size of second subarray
int c[n1], d[n2];
for (int i = 0; i < n1; i++) {
c[i] = a[p + i];
}
for (int j = 0; j < n2; j++) {
d[j] = a[q + 1 + j];
}
.
.
.
}
Now , after this you have copies the both arrays in locally defined arrays. Until this, it is correct .
Now the main part is merging of the two arrays which you are doing in the for loop. You are just comparing the ith element of first sub array with jth element of the second, but what you are missing here is that there may be a time when you have updated all the values of the first( or second) sub array in the main array but still some elements are remaining int the second ( first) one.
For example, take these two subarrays
sub1={2,3,4,5};
sub2={7,8,9,10};
in this case you should break from the loop as soon as you have traversed either of the array completely and copy the rest of the elements of the other array in the same order.
Also in the for loop you increasing k two times in a loop , one in the for statement and another while updating a value, Check that too.
Hope this may solve the problem.
There are couple of things gone wrong in the implementation of your logic. I have indicated them clearly below:
void merge(int*a,int p,int q,int r){ //function to merge two arrays
int n1= (q-p); // size of first sub array
int n2= (r-q); // size of second subarray
int c[n1+1],d[n2]; //you need to add 1 otherwise you will lose out elements
for(int i=0;i<=n1;i++){
c[i]=a[p+i];
}
for(int j=0;j<n2;j++){
d[j]=a[q+j+1];//This is to ensure that the second array starts after the mid element
}
int i=0,j=0;
int k;
for( k=p;k<=r;k++){ // merging two arrays in ascending order
if( i<=n1 && j<n2 ){//you need to check the bounds else may get unexpected results
if( c[i] <= d[j] )
a[k] = c[i++];
else
a[k] = d[j++];
}else if( i<=n1 ){
a[k] = c[i++];
}else{
a[k] = d[j++];
}
}
}

Issue with Merge Sort implementation in C++

I am getting two errors in implementing the algorithm from pseudocode:
One of my problems is int L[n1+1]; error: needs to be a constant; cannot allocate constant size 0. The only way to run this is to make the size a number like 10. I may be implementing the psuedocode wrong that is why I included the statement above that. This may be the cause of my next problem.
My other problem is I am printing only one line of code unsorted. My print function is flawless and works for all of the sorting programs. I believe the MERGE function is only running once. I posted the output of the Sort at the bottom.
I have a random number generator for the array A, from 0 to RAND_MAX.
Initial call is MERGESORT(A,1,n);
void MERGE(int *A, int p, int q, int r)
{
int n1 = q-(p+1);
int n2 = r-q;
//psuedocode states, let L[1..n1+1] & R[1..n1+1] be new arrays
int L[n1+1];
int R[n2+1];
for(int i=1; i<n1;i++)
{
L[i]=A[p+(i-1)];
}
for(int j=1; j<n2; j++)
{
R[j] = A[q+j];
}
L[n1+1]=NULL; //sentinel
R[n2+1]=NULL; //sentinel
int i=1;
int j=1;
for (int k=p; k<r; k++)
{
if(L[i]<=R[j])
{
A[k]=L[i];
i=i+1;
}
else
{
A[k]=R[j];
j=j+1;
}
}
}
void MERGESORT(int *A,int p, int r)
{
if (p<r)
{
int q=floor((p+r)/2);
MERGESORT(A,p,q);
MERGESORT(A,q+1,r);
MERGE(A,p,q,r);
}
}
With int L[10]; and my A[10]; my output is:
Sort: 7474 28268 32506 13774 14411
Press any key to continue . . .
If someone could just assist in the two problems, I more than likely will get it to work.
You are failing to detect the end of your merge arrays:
for (int k=p; k<r; k++)
{
// You need to check that i/j are still in range.
// otherwise the following test are not valid.
if ((i < n1) && (j < n2))
{
if(L[i]<=R[j])
{
A[k]=L[i];
i=i+1;
}
else
{
A[k]=R[j];
j=j+1;
}
}
else
{ /* More work here */
}
Other comments:
Identifiers that are all capitol MERGE MERGESORT are generally reserved for macros. If you use them you are likely to hit problems. Prefer function names of mixed case.
You can simulate arrays with vector:
// Simulate L[1..n1+1]
minI = 1;
maxI = n1-1;
std::vector<int> const L(A+(minI-1), A+(maxI-1));
Arrays in C++ are zero indexed. You seem to be having off by one errors (especially in accessing the end of the array). I would advice you to start the count at 0 rather than 1. Most C++ code is written in terms of iterators from [begining..1PastEnd). I think you will find your algorithm easier to implement if you adapt that style.
There are several issues with your code, I've pointed them out in comments. This is a solution closest to your code, and it's far from best. Consider using C++ containers, like std::vector for example. Naming is at least disputable, and of course merge sort should be implemented as an in place algorithm.
//L and R are auxiliary arrays
//preallocated with (inputSize/2 + 1) constant size
void MERGE(int *A, int p, int q, int r, int* L, int* R)
{
if (p > q || q > r)
{
return;
}
int n1 = q - p + 1;
int n2 = r - q;
// note 0-based indices
int i = 0;
int j = 0;
for(;i < n1;i++)
{
L[i] = A[p + i];
}
for(;j < n2;j++)
{
R[j] = A[q + j + 1]; //+1 because p + n1 - 1 == q + 0
}
//again - note 0-based indices
i = 0;
j = 0;
for (int k = p; k <= r; ++k)
{
// The most important fix - in your code you didn't check
// for left/right array bounds at all.
// Sentinel values aren't needed - size is known
if(i < n1 && (j >= n2 || L[i] <= R[j]))
{
A[k] = L[i];
++i;
}
else if (j < n2)
{
A[k] = R[j];
++j;
}
}
}
void MERGESORT(int* A, int p, int r, int* L, int* R)
{
if (p < r)
{
int q = (p + r) / 2; //floor was redundant
MERGESORT(A, p, q, L, R);
MERGESORT(A, q+1, r, L, R);
MERGE(A, p, q, r, L, R);
}
}
void MERGESORT(int* A, int size)
{
int*L = new int[size/2 + 1]; //preallocate auxiliary arrays
int*R = new int[size/2 + 1]; //size/2 + 1 is what will be needed at most
MERGESORT(A, 0, size - 1, L, R);
delete L;
delete R;
}
int main()
{
int A[5]{ 7474, 28268, 32506, 13774, 14411 };
MERGESORT(A, 5);
for (int i = 0;i < 5;++i)
{
std::cout << A[i] << std::endl;
}
return 0;
}
Output:
7474
13774
14411
28268
32506
Credit goes also to DyP for spotting all the mistakes in the previous version :)