Can't figure out why my Print Array is replacing elements - c++

I'm taking a C++ class and we've gotten to pointers. The assignment we've been given is to basically bubble sort an array that was read from a text file by passing pointers as parameters for various functions. I think I have a decent setup that outputs what I'm looking for, but for specific actions, I'm getting a zero as an element when there isn't one written to the array.
#include <iostream>
#include <fstream>
using namespace std;
int capacity;
int count;
int readData(int *&arr);
void swap(int *xp, int *yp);
void bsort(int *arr, int last);
void writeToConsole(int *arr, int last);
void bubble_sort(int *arr, int last, int(*ptr)(int, int));
int ascending(int a, int b);
int descending(int a, int b);
int main() {
int *whatever = NULL;
count = readData(whatever);
cout << "Raw array data:" << endl;
writeToConsole(whatever, capacity);
cout << "After simple bubble sort:" << endl;
bubble_sort(whatever, capacity, ascending);
writeToConsole(whatever, capacity);
cout << "Now descending:" << endl;
bubble_sort(whatever, capacity, descending);
writeToConsole(whatever, capacity);
return 0;
}
int readData(int *&arr) {
ifstream inputFile;
inputFile.open("data.txt");
if (!inputFile) {
cout << "Error!";
}
inputFile >> capacity;
arr = new int[capacity];
for(int i = 0; i < capacity; i++){
inputFile >> arr[i];
}
inputFile.close();
return capacity;
}
void swap(int *xp, int *yp) {
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void bsort(int *arr, int last) {
int i, j;
bool swapped;
for (i = 0; i < last + 1; i++)
{
swapped = false;
for (j = 0; j < last-i; j++)
{
if (arr[j] > arr[j+1])
{
swap(arr[j], arr[j+1]);
swapped = true;
}
}
// IF no two elements were swapped by inner loop, then break
if (swapped == false)
break;
}
}
void writeToConsole(int *arr, int last) {
cout << "[ ";
for(int i = 0; i < last; i++){
cout << arr[i] << " ";
}
cout << "]" << endl;
}
void bubble_sort(int *arr, int last, int(*ptr)(int, int)){
int i, j;
bool swapped;
for (i = 0; i < last; i++)
{
swapped = false;
for (j = 0; j < last-i; j++)
{
//Use the function pointer to determine which logic to use
if (ptr(arr[j] , arr[j+1]))
{
swap(arr[j], arr[j+1]);
swapped = true;
}
}
// IF no two elements were swapped by inner loop, then break
if (swapped == false)
break;
}
}
int ascending(int a, int b){
return a > b;
}
int descending(int a, int b){
return a < b;
}
My output looks like this:
Raw array data:
[ 8 4 7 2 9 5 6 1 3 ]
After simple bubble sort:
[ 0 1 2 3 4 5 6 7 8 ]
Now descending:
[ 9 8 7 6 5 4 3 2 1 ]
Any ideas as to why my second sort is throwing in a zero? Thank you!

you have to do this change is in bubble_sort function
for (j = 1; j < last - i; j++)
{
//Use the function pointer to determine which logic to use
if (ptr(arr[j-1], arr[j]))
{
swap(arr[j-1], arr[j]);
swapped = true;
}
}

Related

Why does this quicksort program not give an output?

I am giving an integer array as input to an int array and I am expecting an output of sorted ints.
But there is no output.
I tried to use a recursive quicksort algo that will take an array of ints as input and give out a sorted array as output. I was expecting the sorted array to be shown in the terminal but there was no output.
This is the code
#include <iostream>
#define SIZE 10
using namespace std;
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int* array,int p, int q)
{
int key = array[p];
int i = p;
for(int j = p+1; j <= q; j++ )
{
if(key > array[j])
{
i++;
swap(&array[i],&array[j]);
}
}
swap(&array[i],&array[p]);
return i;
}
void quicksort(int* array,int p,int q)
{
if(p < q)
{
int r = partition(array,p,q);
quicksort(array,p,r-1);
quicksort(array,r,q);
}
}
int main()
{
int unsorted[SIZE] = {6,2,5,-1,11,3,17,-9,1,10};
quicksort(unsorted,0,SIZE-1);
cout << "The sorted array" << endl;
for(int i = 0; i < SIZE; i++)
{
cout << unsorted[i] <<" ";
}
}
The code you pasted enters infinite recursion in the quicksort function. Also, I would recommend using std::vector and pass that by reference instead of using C-style arrays. The std::vector is a more flexible container.
Here is the corrected code https://onlinegdb.com/q4LxWciVC:
#include <iostream>
#define SIZE 10
using namespace std;
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int* array,int p, int q)
{
int i = p-1;
int pivot = array[q]; // make pivot the last element of the array
for (int j{p};j<q;++j)
{
if (array[j] < pivot)
{
i++;
swap(&array[i], &array[j]);
}
}
swap(&array[i+1], &array[q]);
return i+1;
}
void quicksort(int* array,int p,int q)
{
if(p >= q){
return;
}
std::cout<<"\n---------Reached here---------\n";
int r = partition(array,p,q);
quicksort(array, p, r-1);
quicksort(array, r+1, q);
}
int main()
{
int unsorted[SIZE] = {6,2,5,-1,11,3,17,-9,1,10};
quicksort(unsorted,0,SIZE-1);
cout << "The sorted array" << endl;
for(int i = 0; i < SIZE; i++)
{
cout << unsorted[i] <<" ";
}
}
Output:
---------Reached here---------
---------Reached here---------
---------Reached here---------
---------Reached here---------
---------Reached here---------
---------Reached here---------
The sorted array
-9 -1 1 2 3 5 6 10 11 17

Sort array using recursion

I have been trying to sort an array using recursion, but I am getting no output, can somebody help me with this, like why there is no output?
void sortarray(int arr[], int index, int key, int len){
if (index == len-2){
}
else{
if (key==len-1){
key=0;
sortarray(arr, index++, key, len );
}
else {
if (arr[key] > arr[key+1]){
swap(arr[key], arr[key+1]);
}
sortarray(arr, index, key++, len );
}
}
}
int main(){
int arr[5] = {5,6,4,3,2};
sortarray(arr, 0,0,5);
for(int i=0; i<5; i++){
cout << arr[i] << " ";
}
}
I fixed the segfault and simplified the code to make it more clear what it does. Namely, walks the array once and swap the key with the next if it's larger. This is not a valid sort algorithm:
#include <iostream>
using namespace std;
void sortarray(int arr[], int key, int len) {
// base case
if (key + 1 == len) return;
// recursive case
if (arr[key] > arr[key + 1]){
swap(arr[key], arr[key + 1]);
}
sortarray(arr, key + 1, len );
}
int main() {
int arr[] = {5,6,4,3,2};
int len = sizeof(arr) / sizeof(*arr);
sortarray(arr, 0, len);
for(int i = 0; i < len; i++) {
cout << arr[i] << " ";
}
return 0;
}
and the result is:
5 4 3 2 6
I made some edits to your code and it works now (don't mind the printArr function, it's there just because cycles in main are ugly):
#include <iostream>
using namespace std;
void printArr(int arr[], int size)
{
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
void sortarray(int arr[], int index, int key, int len)
{
if (index < len)
{
if (key == len - 1) {
key = 0;
sortarray(arr, ++index, key, len);
}
else {
if (arr[key] > arr[key + 1]) {
swap(arr[key], arr[key + 1]);
}
sortarray(arr, index, ++key, len);
}
}
}
int main()
{
int arr[5] = { 5,6,4,3,2 };
cout << "Before sort:" << endl;
printArr(arr, sizeof(arr)/sizeof(*arr));
sortarray(arr, 0, 0, 5);
cout << "After sort:" << endl;
printArr(arr, sizeof(arr) / sizeof(*arr));
return 0;
}
So the first problem was missing iostream and std namespace.
Key changes in the algorithm itself were:
change argument++ to ++argument
change the first condition to (index < len)
As to why your code didn't work properly: the index missed the stopping condition and went over the value of len (thus the screen o' fives).
So this answers your question, but this algorithm you wrote breaks once there are two same values next to each other. There is a good reason we use cycles for sorting and unless recursion is the point, I would recommend abandoning it for this task.
This code works perfectly-:
void sortArr(int arr[],int index, int key, int len){
// static int index = 0;
// static int key = 0;
if (index == len-1){
}
else{
if (key==len-1){
key=0;
sortArr(arr,index+1,key,len );
}
else {
if (arr[key] > arr[key+1]){
swap(arr[key], arr[key+1]);
}
sortArr(arr, index, key+1 ,len );
}
}
}
int main(){
int arr[5] = {5,6,4,3,2};
sortarray(arr, 0, 5);
for(int i=0; i<5; i++) {
cout << arr[i] << " ";
}
return 0;
}
The output of the code is:
2 3 4 5 6

Arrays aren't behaving as I'm expecting

Pointers are still a little confusing to me. I want the split function to copy negative elements of an array into a new array, and positive elements to be copied into another new array. A different function prints the variables. I've included that function but I don't think it is the problem. When the arrays are printed, all elements are 0:
Enter number of elements: 5
Enter list:1 -1 2 -2 3
Negative elements:
0 0
Non-Negative elements:
0 0 0
I assume that the problem is that in the split function below i need to pass the parameters differently. I've tried using '*' and '**' (no quotes) for passing the parameters but I get error messages, I may have done so incorrectly.
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
alpha[i] = bravo[a];
++a;
}
else {
alpha[i] = charlie[b];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}
my main function (all arrays are required to be pointers):
int num_elements;
cin >> num_elements;
int * arr1 = new int[num_elements];
int x;
cout << "Enter list:";
for (int i = 0; i < num_elements; ++i) {
cin >> x;
arr1[i] = x;
}
int y = 0;
int z = 0;
count(arr1, num_elements, y, z);
int * negs = new int [y];
int * nonNegs = new int[z];
split(arr1, negs, nonNegs, num_elements, y, z);
cout << "Negative elements:" << endl;
print_array(negs, y);
cout << endl;
cout << "Non-Negative elements:" << endl;
print_array(nonNegs, z);
cout << endl;
All functions:
void count(int A[], int size, int & negatives, int & nonNegatives) {
for (int i = 0; i < size; ++i) {
if (A[i] < 0) {
++negatives;
}
if (A[i] >= 0) {
++nonNegatives;
}
}
}
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
alpha[i] = bravo[a];
++a;
}
else {
alpha[i] = charlie[b];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}
void print_array(int A[], int size) {
for (int i = 0; i < size; ++i) {
cout << A[i] << " ";
}
}
All help is appreciated.
EDIT: I apologize for my unclear question, I was wondering how to get my arrays to behave as I want them to.
Array is behaving correctly as per instruction :), you are doing minor mistake (may be overlook) in split function. I have commented out the statement and given reason of problem, please correct those two line of code, rest is fine.
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
//alpha[i] = bravo[a];// here alpha is your source array, don't overwrite it
bravo[a] = alpha[i];
++a;
}
else {
//alpha[i] = charlie[b];// here alpha is your source array, don't overwrite it
charlie[b] = alpha[i];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}

heapsort-code is not working

The following code is not working for heap sort. It looks ok to me. Can someone help me please? I have followed the pseudo code from CLRS, the sorted numbers are not being updated after the algorithm is traversed.
#include <iostream>
using namespace std;
void max_heapify(int *b, int i,int he_size)
{
int l,r,largest;
l=2*i;
r=(2*i+1);
if (l<=he_size && b[l]>b[i])
largest=l;
else largest=i;
if (r<=he_size && b[r]> b[largest])
largest=r;
if (largest!=i)
{
swap(b[i],b[largest]);
max_heapify(b,largest,he_size);
}
}
void build_max_heap(int *c,int h_size,int strlength)
{
for (int q=(strlength)/2;q==1;--q)
{
max_heapify(c,q,h_size);
}
}
void swap(int a, int b)
{
int c=b;
b=a;
a=c;
}
int main()
{
int length;
int heap_size;
cout<<"Enter the number of numbers to be sorted by heap sort"<<endl;
cin>>length;
int* a=NULL;
a=new int[length-1];
int temp;
cout<<"Enter the numbers"<<endl;
for(int i=0;i<length;i++)
{
cin>>temp;
*(a+i)=temp;
}
cout<<"The given numbers are:"<<endl;
for(int j=0;j<length;j++)
cout<<*(a+j)<<" "<<endl;
heap_size= length;
build_max_heap(a,heap_size,length);
for (int l=length;l==2;--l)
{
swap(a[1],a[length]);
heap_size=heap_size-1;
max_heapify(a,1,heap_size);
}
cout<<"The sorted numbers are:"<<endl;
for(int j=0;j<length;j++)
cout<<*(a+j)<<" "<<endl;
system("pause");
return 0;
}
The number of mistakes in your code is enormous. Sorry to say it.
void swap(int a, int b)
{
int c=b;
b=a;
a=c;
}
does nothing - a and b should be passed by link, not by value:
void swap(int &a, int &b)
{
int c=b;
b=a;
a=c;
}
for (int q=(strlength)/2;q==1;--q) is wrong. You meant for (int q=(strlength)/2;q>1;--q). Your loop is running only when q==1.
a=new int[length-1]; The size of array should be length, not length-1. And even though swap(a[1],a[length]); is wrong, because a[length] is out of array.
Also there are some mistakes in algorithm. I tried to rewrite as less code as possible.
Right code is:
#include <iostream>
using namespace std;
void sift_down(int *a, int start, int end) {
int root = start;
while (root * 2 + 1 <= end) {
int child = root * 2 + 1;
int sw = root;
if (a[sw] < a[child])
sw = child;
if (child + 1 <= end and a[sw] < a[child + 1])
sw = child + 1;
if (sw == root)
return;
else
swap(a[root], a[sw]);
root = sw;
}
}
void max_heapify(int *b, int count) {
int start = (count - 2) / 2;
while (start >= 0) {
sift_down(b, start, count - 1);
--start;
}
}
void swap(int &a, int &b) {
int c = b;
b = a;
a = c;
}
int main() {
int length;
int heap_size;
cout << "Enter the number of numbers to be sorted by heap sort" << endl;
cin >> length;
int *a = new int[length];
cout << "Enter the numbers" << endl;
for (int i = 0; i < length; i++) {
cin >> a[i];
}
cout << "The given numbers are:" << endl;
for (int j = 0; j < length; j++)
cout << a[j] << " ";
cout << endl;
heap_size = length;
max_heapify(a, heap_size);
--heap_size;
while (heap_size) {
swap(a[heap_size], a[0]);
--heap_size;
sift_down(a, 0, heap_size);
}
cout << "The sorted numbers are:" << endl;
for (int j = 0; j < length; j++)
cout << a[j] << " ";
cout << endl;
//system("pause");
return 0;
}

quicksort string array help c++

This is my code. I don't know how to get the code to run. Im having problems with quicksorting for string.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include <string>
#include <ctime>
#include <stdio.h>
using namespace std;
int count;
template <class T>
void printArray(T ar[], int sz);
template <class T>
void bubbleSort(T ar[], int sz);
void quickSortMain(string items[], int ct);
void quickSort(string items[], int left, int right);
//////////////////////////////////////////////////////////////////////////
// Main Function Implementation
//////////////////////////////////////////////////////////////////////////
int main() {
int numOfData = 50000;
string line, temp;
ofstream resultFile;
ofstream tableFile;
double data[100][2];
string patient[numOfData];
ifstream dataFile("shufflePatient.txt");
int i;
int SIZE = 0;
cout << "Program to shuffle data" << endl << endl;
cout << "This program will calculate swapping processes and running time.";
/*Storing data*/
cout << "Reading data in process.." << endl;
if (dataFile.is_open()) {
i=-1;
while (dataFile.good()) {
getline (dataFile, line);
if (i>=0) patient[i] = line;
i++;
}
dataFile.close();
}
SIZE = 5;
quickSortMain(patient, 5);
/*Writing to file*/
cout << "Writing to file.." << endl;
resultFile.open ("test.txt");
for (int i=0 ; i<numOfData ; i++) {
resultFile << patient[i] << "\n";
}
resultFile.close();
system("pause");
return 0;
}
void quickSortMain(string items[], int ct)
{
quickSort(items, 0, ct-1);
}
void quickSort(string items[], int left, int right)
{
int i, j;
char *x;
string temp[10];
i = left;
j = right;
x = items[(left+right)/2];
do {
while((strcmp(items[i],x) < 0) && (i < right)) {
i++;
}
while((strcmp(items[j],x) > 0) && (j > left)) {
j--;
}
if(i <= j) {
strcpy(temp, items[i]);
strcpy(items[i], items[j]);
strcpy(items[j], temp);
i++;
j--;
}
} while(i <= j);
if(left < j) {
quickSort(items, left, j);
}
if(i < right) {
quickSort(items, i, right);
}
}
//----------------------------------------------------------------------------
// prints array of size size
//----------------------------------------------------------------------------
template <class T>
void printArray(T patient[], int size)
{
for(int i = 0; i < size; i++)
cout << patient[i] << " ";
cout << endl;
}
//----------------------------------------------------------------------------
// sorts array of size size by Bubble Sort method
//----------------------------------------------------------------------------
template <class T>
void bubbleSort(T patient[], int size) //returning an int
{
bool noChange = true;
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
}
}
if (noChange)
return ;
}
}
The error i got was in this line:
x = items[(left+right)/2];
I changed
char x*; to string x;
I don't know if that was correct. Now the error im getting is that strcmp and strcpy are not declared. Any help on what i should do next?
That's correct, now change
strcmp(items[i],x) < 0
to
items[i] < x
and
strcmp(items[j],x) > 0
to
items[j] > x
and
strcpy(temp, items[i]);
to
temp = items[i];
etc.
But really this is a case of RTFM. If you're competent enough to write a quicksort routine you should be competent enough to look up how std::string works. Being able to access reference information is a very important skill for a programmer.