Errors Within Void Merge - c++

I've been having problems trying to figure out how to fix this code I wrote for Mergesort.
The intended result was to output a sorted array of inputs, but the void merge function contains errors that result in either an unsorted array or an array of really large or small numbers.
I've tried many times to fix them, but the result still doesn't come out perfectly.
Can you look it over and tell me what I've been doing wrong?
#include "pch.h"
#include <iostream>
using namespace std;
void merge(int* arr, int p, int q, int r) {
//copy A[p.q] into L
//and A[q+1.r] into R
int i, j, k;
int n1 = q - p + 1;
int n2 = r - q;
int* L = new int[n1+1];
int* R = new int[n2+1];
for (i = 1; i <= n1; i++) {
L[i] = arr[p+i-1];
}
for (j = 1; j <= n2; j++){
R[j] = arr[q+j];
}
L[n1+1] = 99999;
R[n2+1] = 99999; //represents infinity
i = j = 1;
for (k = p; k <= r; k++)
{
if (L[i] <= R[j]) {
arr[k] = L[i];
i = i + 1;
}
else {
arr[k] = R[j];
j = j + 1;
}
return;
}
}
void mergesort(int* arr, int p, int r) {
if (p < r) {
int q = floor((p + r) / 2);
mergesort(arr, p, q);
mergesort(arr, q + 1, r);
merge(arr, p, q, r);
}
return;
}
int main() {
int r;
cin >> r;
int* arr = new int[r];
for (int i = 0; i < r; i++) {
int num;
cin >> num;
arr[i] = num;
}
int p = 0;
//sortint function
mergesort(arr,p,r);
for (int i = 0; i < r; i++) {
cout << arr[i] << ";";
}
return 0;
}

Related

C++ Merge Sort returning original vector

I have been attempting to make a merge sort using vectors in C++ and am running into an issue where any vector input is sorted into its original order. I have based the algorithm off the geeks4geeks site here: https://www.geeksforgeeks.org/merge-sort/
So far I have spent about five hours attempting to find the source of the error and it seems that upon ending the merge function the vector somehow goes back to its original format, but I am unsure why. Any suggestions would be much appreciated.
#include <iostream>
#include <vector>
using namespace std;
void merge(vector<int> vect, int p, int q, int r) {
int i, j, k, n1, n2;
n1 = q - p + 1;
n2 = r - q;
vector<int> L, R;
L.resize(n1);
R.resize(n2);
for (i = 0; i < n1; i++) {
L[i] = vect[p + i];
}
for (j = 0; j < n2; j++) {
R[j] = vect[q + 1 + j];
}
i = 0;
j = 0;
k = p;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
vect[k] = L[i];
i++;
}
else {
vect[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
vect[k] = L[i];
i++;
k++;
}
while (j < n2) {
vect[k] = R[j];
j++;
k++;
}
}
void mergeSort(vector<int> vect, int p, int r) {
if (p < r) {
int q = (p + r) / 2;
mergeSort(vect, p, q);
mergeSort(vect, q + 1, r);
merge(vect, p, q, r);
}
}
int main() {
vector<int> vect{4,3,5,6,7,8};
mergeSort(vect, 0, vect.size() - 1);
for (int i = 0; i < vect.size(); i++) {
cout << vect[i] << endl;
}
}
First of all you should know the difference between:
pass by value
pass by reference
Go and check it here.
Secondly, you should change your code as it is shown:
#include <iostream>
#include <vector>
//using namespace std; forget about it, start using std::whatever_it_is_in_here
void merge(std::vector<int> &vect, int p, int q, int r) // note the & near vect
{
int i, j, k, n1, n2;
n1 = q - p + 1;
n2 = r - q;
std::vector<int> L, R;
L.resize(n1);
R.resize(n2);
for (i = 0; i < n1; i++) {
L[i] = vect[p + i];
}
for (j = 0; j < n2; j++) {
R[j] = vect[q + 1 + j];
}
i = 0;
j = 0;
k = p;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
vect[k] = L[i];
i++;
}
else {
vect[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
vect[k] = L[i];
i++;
k++;
}
while (j < n2) {
vect[k] = R[j];
j++;
k++;
}
}
void mergeSort(std::vector<int> &vect, int p, int r) // note the & near vect
{
if (p < r) {
int q = (p + r) / 2;
mergeSort(vect, p, q);
mergeSort(vect, q + 1, r);
merge(vect, p, q, r);
}
}
int main()
{
std::vector<int> vect{4,3,5,6,7,8};
mergeSort(vect, 0, vect.size() - 1);
for (int i = 0; i < vect.size(); i++)
std::cout << vect[i] << "\n"; // note \n instead of std::endl
return 0; // you forgot the return statement
}
You forgot the return statement in the main function.
Stop using using namespace std. Check why here
Note the "\n" instead of std::endl. You can understand more of it here

Merge_sort without sentinel

Can someone please tell me why I am getting garbage value after sorting?
Initial call is (A,0,n) where n is the size of array? I want to sort the array using merge sort algorithm but without sentinel value.
void merge_sort(int A[], int l, int mid, int r)
{
int n1 = mid - l + 1;
int n2 = r - mid;
int L[n1], R[n2];
for (int i = 0; i < n1; i++)
{
L[i] = A[i];
}
for (int i = 0; i <= n2; i++)
{
R[i] = A[i + mid + 1];
}
cout << endl;
int j = 0, k = 0;
for (int i = l; i < r; i++)
{
if (j == n1 || k == n2)
{
if (j == n1 + 1)
{
A[i] = R[k];
k++;
}
else
{
A[i] = L[j];
j++;
}
}
else if (L[j] >= R[k])
{
A[i] = L[j];
j++;
}
else
{
A[i] = R[k];
k++;
}
}
}
void merge_divide(int A[], int l, int r)
{
if (l < r)
{
int mid = (l + r) / 2;
merge_divide(A, l, mid);
merge_divide(A, mid + 1, r);
merge_sort(A, l, mid, r);
}
}
There are a lot of moves in your logic that is hard to read. It is hard to distinguish where is an error or there is some intention here. But here it is how I see it with fixes. See inline comments.
void merge_sort(int A[], int l, int mid, int r) {
int n1 = mid - l;
int n2 = r - mid;
// this is C, but not C++, consider using vector instead
int L[n1], R[n2];
for (int i = 0; i < n1; i++) {
// need `l` here
L[i] = A[l + i];
}
for (int i = 0; i < n2; i++) {
// need to include `mid`
R[i] = A[i + mid];
}
int j = 0, k = 0;
for (int i = l; i < r; i++) {
if (j == n1) {
A[i] = R[k];
k++;
} else if (k == n2) {
A[i] = L[j];
j++;
} else if (L[j] >= R[k]) {
A[i] = L[j];
j++;
} else {
A[i] = R[k];
k++;
}
}
}
void merge_divide(int A[], int l, int r) {
// need properly compute `mid` here
int mid = r - l;
if (mid > 1) {
mid = l + mid / 2;
merge_divide(A, l, mid);
merge_divide(A, mid, r);
merge_sort(A, l, mid, r);
}
}
int main() {
int A[] = {2, 4, 3, 382, 2342334, 3, 42, 234};
int n = sizeof(A) / sizeof(int);
merge_divide(A, 0, n);
for (int i = 0; i < n; ++i)
cerr << A[i] << " ";
cout << endl;
}

Merge Sort Algorithm?

I can't figure out what is wrong with my MergeSort function. This is my code:
void Merge(int* A, int p, int q, int r)
{
int B[100], i = 0, j = 0, k = 0;
i = p;
k = p;
j = q + 1;
while (i <= q && j <= r)
{
if (A[i] <= A[j])
{
B[k] = A[i];
k++;
i++;
}
else
{
B[k] = A[j];
k++;
j++;
}
}
while (i <= q)
{
B[k] = A[i];
k++;
i++;
}
while (j <= r)
{
B[k] = A[j];
k++;
j++;
}
for (i = p; i < r; i++)
{
A[i] = B[i];
}
}
void MergeSort(int A[], int p, int r)
{
int q;
if (p < r)
{
q = (p + r) / 2;
MergeSort(A, p, q);
MergeSort(A, q + 1, r);
Merge(A, p, q, r);
}
}
int main(void)
{
int N[10];
N[0] = 4;
N[1] = 5;
N[2] = 8;
N[3] = 12;
N[4] = 7;
N[5] = 3;
N[6] = 23;
N[7] = 1;
N[8] = 90;
N[9] = 26;
MergeSort(N, 0, 9);
for (int i = 0; i < 10; i++)
{
cout << N[i] << endl;
}
}
The output of program is: 1, 3, 1, 4, 5, 7, 7, 7, 26, 26, which is obviously wrong. However I just don't see what is wrong in code, to me everthing looks good. I googled some C++ codes of MargeSort and try to debug it but i can't find mistake. Anyone see it?
//you have just one err,in last for you missed = :
//err: for(i = p; i < r; i++)
//correct: for(i = p; i <= r; i++)
#include <iostream>
using namespace std;
void Merge(int* A, int p, int q, int r)
{
int B[100], i = 0, j = 0, k = 0;
i = p;
k = p;
j = q + 1;
while (i <= q && j <= r)
{
if (A[i] <= A[j])
{
B[k] = A[i];
k++;
i++;
}
else
{
B[k] = A[j];
k++;
j++;
}
}
while (i <= q)
{
B[k] = A[i];
k++;
i++;
}
while (j <= r)
{
B[k] = A[j];
k++;
j++;
}
for (i = p; i <= r; i++)
{
A[i] = B[i];
}
}
void MergeSort(int A[], int p, int r)
{
int q;
if (p < r)
{
q = (p + r) / 2;
MergeSort(A, p, q);
MergeSort(A, q + 1, r);
Merge(A, p, q, r);
}
}
int main(void)
{
int A[10]={9,8,7,6,5,4,3,2,1,0};
MergeSort(A,0,9);
for (int i = 0; i<10; i++)
{
cout<<A[i]<<",";
}
}
//this is cleaned version of your code:
#include <iostream>
using namespace std;
void Merge(int* A, int p, int q, int r)
{
int* B=new int[r-p+1];
int i = p;
int j = q + 1;
int k = 0;
while (i <= q && j <= r) B[k++] = (A[i] <= A[j])? A[i++] : A[j++];
while (i <= q) B[k++] = A[i++];
while (j <= r) B[k++] = A[j++];
for (i = p; i <= r; i++) A[i] = B[i-p];
delete B;
}
void MergeSort(int* A, int p, int r)
{
if (p >= r) return;
int q = (p + r) / 2;
MergeSort(A, p, q);
MergeSort(A, q + 1, r);
Merge(A, p, q, r);
}
int main(void)
{
int A[15]={10,11,12,13,14,0,8,7,6,5,4,3,2,1,9};
MergeSort(A,0,14);
for (int i = 0; i<15; i++) cout<<A[i]<<",";
}
//this is another answer:
#include <iostream>
#include <climits>
using namespace std;
static void Merge(int* A, int p, int q, int r)
{
int n1 = q - p + 1;// A[p..q]
int n2 = r - q;// A[q+1..r]
int* L = new int[n1 + 1];
int* R = new int[n2 + 1];
int i, j;
for (i = 0; i < n1; i++)
L[i] = A[p + i];
for (i = 0; i < n2; i++)
R[i] = A[q + i+1];
L[n1] = INT_MAX;
R[n2] = INT_MAX;
i = 0;
j = 0;
for (int k = p; k <= r; k++)
A[k] = L[i] <= R[j] ? L[i++] : R[j++];
delete L;
delete R;
}
static void Ascending(int* A, int p, int r)
{
if (p >= r) return;
int q = (p + r) / 2;
Ascending(A, p, q);
Ascending(A, q + 1, r);
Merge(A, p, q, r);
}
int main()
{
int A[10]={9,8,7,6,5,4,3,2,1,0};
Ascending(A,0,9);
for (int i = 0; i<10; i++)
{
cout<<A[i]<<",";
}
}

mergesort in C++

#include "stdafx.h"
#include <iostream>
using namespace std;
using namespace System;
void mergesort(int a[], int p, int r);
void merge(int a[], int p, int q, int r);
int main(array<System::String ^> ^args)
{
int result[2] = { 1, 0 };
int *p;
p = result;
mergesort(p, 0,1);
while (1);
return 0;
}
void mergesort(int a[],int p, int r)
{
if (p < r)
{
int q = (p + r) / 2;
mergesort(a, p, q);
cout << endl;
mergesort(a, q + 1, r);
cout << endl;
merge(a,p,q,r);
for (int i = 0; i < 2; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
}
void merge(int a[], int p, int q, int r)
{
int left[100] = {};
int right[100] = {};
for (int i = 0; i < (q - p + 1); i++)
{
left[i] = *(a + p + i);
left[i + 1] = 999;
}
for (int i = 0; i < (r - q); i++)
{
right[i] = *(a + q + 1 + i);
right[i + 1] = 999;
}
for (int k = p; k < r+1; k++)
{
int i = 0;
int j = 0;
if (left[i] <= right[j])
{
a[k] = left[i++];
}
else
{
a[k] = right[j++]; **// it always goes into this route? why does not left[i]<=right[j] work?**
}
}
}
Here is my code about a basic merge sort. I cannot enter the first IF statement in the merge function. Why does if (left[i] <= right[j]) not work? I have tried may time whatever the left[i] is. The program just goes to the else statement.
for (int k = p; k < r+1; k++)
{
int i = 0;
int j = 0;
if (left[i] <= right[j])
{
a[k] = left[i++];
}
else
{
a[k] = right[j++]; **// it always goes into this route? why does not left[i]<=right[j] work?**
}
}
This does not do what you think it does. It will always compare left[0] with right[0], because you declare i and j inside the for loop, so they will be reset to 0 on each iteration.
To make them retain their values, declare them outside the loop:
int i = 0;
int j = 0;
for (int k = p; k < r+1; k++)
{
if (left[i] <= right[j])
{
a[k] = left[i++];
}
else
{
a[k] = right[j++]; **// it always goes into this route? why does not left[i]<=right[j] work?**
}
}
If your intent is to use variables i and j in the loop only then try to restrict the scope of i and j to the loop by doing following.
for (int k = p, i = 0, j = 0; k < r+1; k++)
{
if (left[i] <= right[j])
{
a[k] = left[i++];
}
else
{
a[k] = right[j++];
}
}

Designing MERGE-SORT Algorithm - VERY WEIRD ISSUE ! "std::bad_alloc at memory location 0x00486F78."

This is for an assignment in an algorithm class. I understand and agree that using a vector would simplify things, but that isn't an option.
The code for the Mergesort / merge algorithm can't be modified either.
I need to run the merge sort as follows:
starting from 100 all the way to 1000, increments of 100. For each increment I run it 5 times, for each of these times I run it 1000 times.
That being said - everything works fine until my loop reaches 700 and crashes with the error: "Unhandled exception at 0x75612F71 in msdebug.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x010672F4."
Here is my code:
int const size = 6;
int const size2 = 1001;
int const times = 6;
int const interval = 11;
void merge(int arr[], int p, int q, int r)
{
int n1 = q - p + 1;
int n2 = r - q;
int * L = new int[n1 + 1];
int * R = new int[n2 + 1]; // line giving the error after 700
for (int i = 1; i <= n1; i++)
{
L[i] = arr[p + i - 1];
}
for (int j = 1; j <= n2; j++)
{
R[j] = arr[q + j];
}
L[n1 + 1] = 32768;
R[n2 + 1] = 32768;
int i, j;
i = j = 1;
for (int k = p; k <= r; k++)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
}
}
void mergeSort(int arr[], int p, int r)
{
int q;
if (p < r)
{
q = ((p + r) / 2);
mergeSort(arr, p, q);
mergeSort(arr, (q + 1), r);
merge(arr, p, q, r);
}
}
void copyArray(int original[][size2], int copy[], int row, int finish)
{
int i = 1;
while (i <= finish)
{
copy[i] = original[row][i];
i++;
}
}
void copyOneD(int orig[], int cop[])
{
for (int i = 1; i < size2; i++)
{
cop[i] = orig[i];
}
}
int main()
{
struct timeval;
clock_t start, end;
srand(time(NULL));
int arr[size][size2];
int arr2[size2];
int arrCopy[size2];
double tMergeSort[times][interval];
double avgTmergeSort[11];
/*for (int i = 1; i < (size2); i++)
{
arr2[i] = rand();
}*/
for (int i = 1; i < size; i++)
{
for (int j = 1; j < size2; j++)
{
arr[i][j] = rand();
}
}
for (int x = 100; x <= 1000; x = x + 100) //This loop crashes >=700
{
for (int r = 1; r <= 5; r++)
{
copyArray(arr, arr2, r, 1001);
for (int k = 0; k < 1000; k++)
{
copyOneD(arr2, arrCopy);
mergeSort(arrCopy, 1, x);
}
}
}
return 0;
}
You can ignore the code and the arrays. Those functions work fine.
Everything works fine until I set 'x <= 700' or higher and then it crashes.
I had a theory that maybe the computer runs out of memory for the pointers in the merge algorithm but when I tried to use delete it also crashed.
Any help is appreciated and suggestions as well.
Thanks