0

When I call my print function, my program displays the unsorted data after I've ran it through bubble sort. I've compared my code to friends and an article about bubble sort I found on geeksforgeeks (https://www.geeksforgeeks.org/bubble-sort/) and for whatever reason my data won't sort.

I'm writing a program for my college data structures class with 4 sorting functions. What is supposed to happen in theory is the program reads in a data file with 8000 random numbers and sorts the data based on which sort is called (bubble sort, insert sort, selection sort, and quick sort). A print function is called and will display every 1000th data element to show that the data is indeed sorted. I've tried coding my print in main, putting the print call in the sorting function, and using a function to print, Quadruple checked my sorting function. I've also tried different compilers and a different computer but I suspect it's something funky with my code.

Original code:

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
const int arraysize = 8000;
int numcompares, numcopies;
void swapem(double a, double b)
{
    double temp;
    temp = a;
    a = b;
    b = temp;
}
void bubblesort(double r[], int n)
{
    int j, i;
    for (j = 0; j < n - 1; j++)
    {
        for (i = 0; i < n - 1; i++)
        {
            numcompares++;
            if (r[i] > r[i + 1])
            {
                swapem(r[i], r[i + 1]);
                numcopies += 3;
            }
        }
    }
}
void printem(double r[])
{
    cout <<  r[1000] << ", " << r[2000] << ", " << r[3000] << ", " <<
    r[4000] << ", " << r[5000] << ", " << r[6000] << ", " << r[7000] << ", " << r[7999] << endl;
}
int main()
{
    ifstream inf("data.dat");
    ofstream outf("sorted.ot");
    string sortname;
    double arraynums[arraysize];
    for (int i = 0; i < arraysize; i++)
    {
        inf >> arraynums[i];
    }
    bubblesort(arraynums, arraysize);
        system("pause");
    return 0;
}

I've tried:

void printem(double r[], int n)
{
    int i;
    for (i = 0; i < n; i++)
        cout << r[i]<< ", ";    
}
printem(arraynums,20); // in main

and in main

for (int i = 0; i < 10; i++)
    {
        cout << arraynums[i] << endl;
    } 


Here's 10 of the 8000 random integers that refuse to be sorted

41275.4
12113.1
50676
7662.34
50688.3
-7926.28
13672.8
-3212.9
-13046.5
-16798

The output should be: -16798 -13046.5 -7926.28 -3212.9 7662.34 12113.1 13672.8 41275.4 50676 50688.3

Yet it stays in it's unsorted form: 41275.4 12113.1 50676 7662.34 50688.3 -7926.28 13672.8 -3212.9 -13046.5 -16798

Andy
  • 23
  • 1
  • 4

2 Answers2

1

Welcome to Stack Overflow! It seems like what you have here is a classic case of pass by value vs pass by reference. A function in C cannot modify the values of its parameters outside of its own scope, but it can access memory referenced by its parameters and modify that.

swapem() only makes changes to a and b in the scope of the method itself, but does not update the data referenced at the positions of a and b. To resolve this, you can pass a and b in as pointers, and modify the values referenced by the pointers, like so:

void swapem(double *a, double *b) {
     double temp = *a;
     *a = *b;
     *b = temp;
}

And the method itself would take the references of those array elements instead of their values. For the above example, it would look like this:

swapem(r + i, r + (i + 1))

There is a good set of related information here on pass by value and pass by reference. There is a bit of a technicality in that you're actually passing the value of the pointer into the above examples which technically makes it pass by value, but it's a reference to the actual variable you're trying to modify, so the concept still holds true here.

TCFP
  • 189
  • 1
  • 6
0

It is important to understand what your bubblesort() function does. It receives a COPY of the array members 'arraynums'. It does the sorting on it and then terminates. At the end of this function, you don't have this sorted array with you.

But wait, even your swapem() won't work, as it will also be receiving a copy of the 2 values and do the swapping locally. You won't be having the swapped values after this call.

To remedy this, you need to use pass-by-reference in swapem() function.

void swapem(double & a, double & b)
{
    double temp;
    temp = a;
    a = b;
    b = temp;
}

In the bubbelsort() function, you can straight away use your printem() function if you want bubblesort to do the printing. Instead you can simply pass the array as reference to bubblesort() and at the end of it you will have the modified arraynums array.

Saket Sharad
  • 392
  • 2
  • 11
  • The `bubblesort ` call receives the array address, no copying happening there. The second point about `swapem` is valid. – Lutz Lehmann Apr 30 '19 at 16:00