How do I fix my quickSort implementation? - c++

So I've been trying to implement a quicksort but it seems not working
It keeps giving me a segmentation fault error 11
Can someone please help or give an advice on fixing this?
#include <iostream>
using namespace std;
void _quickSort(int arr[],int lo,int hi);
void quickSort(int arr[]) {
//lo = low(arr);
//hi = high(arr);
_quickSort(arr,0,9);
}
void _quickSort(int arr[], int lo, int hi) {
int p = lo;
//cout << lo << " " << hi << endl;
for (int i = lo; i < hi;i++) {
if (arr[i] < arr[p]) {
cout<<arr[i]<<" <-> "<<arr[p]<<endl;
swap(arr[i],arr[p]);
p = i;
}
}
_quickSort(arr,lo,p);
_quickSort(arr,p,hi);
}
int main() {
int a[] = {5,2,7,9,8,3,1,6,4};
quickSort(a);
for (int i = 0;i < 9;i++) {
cout << a[i] << " ";
}
}

#include <bits/stdc++.h>
using namespace std;
int _quickSort(int a[], int lb, int ub) {// lb-lower bound ub-upperbound
int start=lb;
int end=ub;
int pivot=a[lb];
while(start<end)
{
while(a[start]<=pivot)
start++;
while(a[end]>pivot)
end--;
if(start<end)
{
int temp=a[end];
a[end]=a[start];
a[start]=temp;
//cout<<a[start]<<" "<<a[end]<<" "<<pivot<<"\n";
}
}
int temp=a[end];
a[end]=a[lb];
a[lb]=temp;
return end;
}
void quickSort(int a[],int lb,int ub) {
if(lb<ub)
{
int pos=_quickSort(a,lb,ub);
quickSort(a,lb,pos-1);
quickSort(a,pos+1,ub);
}
}
int main() {
int a[9] = {5,2,7,9,8,3,1,6,4};
quickSort(a,0,8);
for (int i = 0;i <=8;i++)
{
cout << a[i] << " ";
}
}
This is an alternative way of implementing quicksort. Ive just returned the position of the pivot to another function and recursively calling the _quicksort from that.

Related

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

How do I access all elements to my array that i'm pointing at and change them during a mergeSort function call?

I have a mergeSort function that I have tested and it works when I have the function in main(). I'm trying to implement it into a class right now but when I print out the array elements after sorting it, they are not sorted. I think that my problem lies in how I'm accessing my array elements, and what I'm doing with them.
Main.cpp
#include <iostream>
#include "Sort.h"
using namespace std;
int main() {
Sort temp(10);
temp.InitArray();
cout << "Unsorted: ";
temp.Print();
temp.MergeSort(0, 9);
cout << "Sorted: ";
temp.Print();
cout << "end" << endl;
cin.get();
return 0;
}
Sort.h
#ifndef __SORT__
#define __SORT__
class Sort
{
public:
Sort(int arraySize);
~Sort();
void InitArray();
void MergeSort(int low, int high);
void Print();
private:
int *myArray;
int size;
void MergeSortRecursionHelper(int indexL, int indexM, int indexH);
};
#endif
Sort.cpp
#include <random>
#include <iostream>
#include "Sort.h"
Sort::Sort(int arraySize){
myArray = new int[arraySize];
size = arraySize;
}
Sort::~Sort(){
delete [] myArray;
}
void Sort::InitArray() {
for(int i = 0; i < size; i++){
myArray[i] = rand() % 100;
}
}
void Sort::MergeSort(int low, int high) {
//base case
if(myArray[high] <= myArray[low]){
return;
}
int mid = (low + high) / 2;
MergeSort(low, mid);
MergeSort(mid + 1, high);
MergeSortRecursionHelper(low, mid, high);
}
void Sort::MergeSortRecursionHelper(int indexL, int indexM, int indexH)
{
int mSize = indexH - indexL + 1;
int* mergedData = new int[mSize];
int mergedIndex = 0;
int rightInd = indexM + 1;
int leftInd = indexL;
while(leftInd <= indexM && rightInd <= indexH){
if(myArray[indexL] < myArray[rightInd]){
mergedData[mergedIndex++] = myArray[leftInd++];
}else{
mergedData[mergedIndex++] = myArray[rightInd++];
}
}
while(leftInd <= indexM){
mergedData[mergedIndex++] = myArray[leftInd++];
}
while(rightInd <= indexH){
mergedData[mergedIndex++] = myArray[rightInd++];
}
for(int i = indexL; i < indexH + 1; i++){
myArray[i] = mergedData[i - indexL];
}
delete[] mergedData;
}
void Sort::Print(){
for(int i = 0; i < size; i++){
std::cout << " " << myArray[i];
}
std::cout << std::endl;
}
Your first check in your if is not right. Just because, e.g. input {8,4,100,7}, doesn't mean it's sorted due to 7 < 8.
void Sort::MergeSort(int low, int high) {
//base case
if(myArray[high] <= myArray[low]){
return;
}

How to print an array in descending order?

Basically this is my code and it works fine. I just don't know how to print it in descending order. This code basically shows the odd numbers:1,3,5,7. I want it to be printed 7,5,3,1. I know I need use the sort function but I dont know how.
#include <iostream>
using namespace std;
void fillArray(int arr[], int &n);
void printArray(int arr[], int n);
void findSum(int arr[], int &n);
int main()
{
int n;
cin>>n;
int arr[n];
fillArray(arr,n);
printArray(arr,n);
findSum(arr,n);
return 0;
}
void fillArray(int arr[], int &n)
{
int j=1;
for(int i=0;i<n;i++)
{
if(j%2==1)
arr[i]=j;
else
i--;
j++;
}
}
void printArray(int arr[], int n)
{
for(int i=0;i<n;i++)
{
cout<<arr[i]<<", ";
}
}
void findSum(int arr[], int &n)
{
int sum=0;
for(int i=0;i<n;i++)
{
sum=sum+arr[i];
}
}
for(int i = n-1; i >= 0; i--)
{
cout << arr[i] << ", ";
}
example:
void printArray(int *tab, int size)
{
for (int i = size - 1; i >= 0; i--)
std::cout << tab[i] << std::endl;
}
int main() {
int tab[3] = { 1,2,3 };
printArray(tab, 3);
}
You should begin from last element array, and decrement iterator (i) to i == 0
You can simply use a sort function. There is one included with the algorithm header.
#include <algorithm> // this goes at the top
void printArray(int arr[], int n)
{
sort(arr, arr+n, [](int x, int y){return y<x;});
for(int i=0;i<n;i++)
cout << arr[i] << endl;
}
the [](int x, int y){return y<x;} part is just to make it descending. Normally it is y>x, at which point you can just omit the third parameter
Here is a repl:
https://repl.it/JQor/0

After reading the theory of Merge Sort , I tried to write an implementation of Merge Sort, but its stuck

After reading through the theory of Merge Sort on TopCoder, I tried to write it's implementations, but it's getting weird, and I'm more or less a beginner in programming, especially algorithms. Can somebody assist me?
#include <iostream>
using namespace std;
int arr[] = {2, 0, 43, 12, 98};
int sizeOfarr(int a[])
{
return sizeof(a)/sizeof(a[0]);
}
int minElement(int x, int y)
{
if (x > y)
{
return y;
}
else if (x < y)
{
return x;
}
else
{
return x, y;
}
}
int main()
{
int t, z;
int n = sizeOfarr(arr);
int finalList[n];
int list1[n];
int list2[n];
for(int i = 0; i<=((n/2)-1); i++)
{
list1[i] = arr[i];
}
for(int j = n/2; j<n; j++)
{
for(int k = 0; k<=((n/2)-1); k++ )
{
list2[k] = arr[j];
}
}
for(int y = 0; y<=n; y++)
{
while(sizeOfarr(finalList)!=n)
{
t = list1[0];
z = list2[0];
finalList[y] = minElement(t, z);
if(finalList[y]==t)
{
list1[0] = list1[1];
}
else if(finalList[y]==z)
{
list2[0] = list2[1];
}
else
{
list1[0] = list1[1];
list2[0] = list2[1];
}
}
}
cout << "The sorted list is: " << finalList << endl;
return 0;
}
#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;
int temp[10000];
void merge(int *A,int low,int mid,int high)
{
int i=low;
int j=mid+1;
int k=low;
int l;
while(i<=mid && j<=high)
{
if(A[i]<A[j])
{
temp[k]=A[i];
i=i+1;
}
else
{
temp[k]=A[j];
j=j+1;
}
k++;
}
for(l=i;l<=mid;l++,k++)
{
temp[k]=A[l];
}
for(l=j;l<=high;l++,k++)
{
temp[k]=A[l];
}
memcpy(A,temp,sizeof(A[0])*k);
}
void mergeSort(int *A,int low,int high)
{
int mid;
if(low<high)
{
mid=floor((low+high)/2);
mergeSort(A,low,mid);
mergeSort(A,mid+1,high);
merge(A,low,mid,high);
}
}
int main(int argc,char *argv[])
{
int n;
int array[10000];
cout<<"please enter the number numbers\n";
cin>>n;
cout<<"please enter the nubers\n";
for(int i=0;i<n;i++)
{
cin>>array[i];
}
mergeSort(array,0,n-1);
for(int i=0;i<n;i++)
{
cout<<array[i]<<" ";
}
cout<<"\n";
}
This is my implementation
mergeSort function divide recursively at middle and repeats until low lt(less than) high then a merge function is called.
I see from your code that the operator "," (return x,y) would replace x value by y value.
A few comments on the code:
return x,y // this just returns y. this is the case when x==y so it probably is OK bit not what one would write.
while(sizeOfarr(finalList)!=n) // The size of your array finalist is n elements. This is never going to change so this while condition is always false and the loop will never execute.

Count the number of component wise comparisons in quicksort algorithm.

I'm trying to count the number of comparisons my quicksort algorithm makes for an array size of 500. I know that the best case for quicksort with partition is nlogn-n+1. So for an array size of 500, the best case number of component wise comparisons would be about 3983. However, when I run my code, I'm getting 2400 comparisons or so, depending on the array the random function generates. Am I counting the number of component wise comparisons wrong? Please help.
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int count_500 = 0;
int partition(int *S,int l, int u);
void swap(int &val1, int &val2);
void Quicksort(int S[],int low, int hi);
void exchange(int list[], int p, int q);
int median_of_3(int list[], int p, int r);
void Quicksort_M3(int S[], int low, int hi);
int main()
{
int S1_500[500];
int S2_500[500];
int S3_500[500];
int S1_200[200];
int S2_200[200];
int S3_200[200];
int S1_8[8];
int S2_8[8];
int S3_8[8];
srand ( time(NULL) );
for(int i=0; i<500; i++)
{
S1_500[i] = rand()%1000;
S2_500[i] = rand()%1000;
S3_500[i] = rand()%1000;
}
for(int i=0; i<200; i++)
{
S1_200[i] = rand()%500;
S2_200[i] = rand()%500;
S3_200[i] = rand()%500;
}
for(int i=0; i<8; i++)
{
S1_8[i] = rand()%100;
S2_8[i] = rand()%100;
S3_8[i] = rand()%100;
}
Quicksort(S1_500,0,499);
for(int i=0; i<500; i++)
{
cout << S1_500[i] << endl;
}
cout << "Number of component wise comparisons is: " << count_500 << endl;
}
int partition(int *S,int l, int u)
{
int x = S[l];
int j = l;
for(int i=l+1; i<=u; i++)
{
if(S[i] < x)
{
count_500++; // Count the component wise comparison
j++;
swap(S[i],S[j]);
}
}
int p = j;
swap(S[l],S[p]);
return p;
}
void swap(int &val1, int &val2)
{
int temp = val1;
val1 = val2;
val2 = temp;
}
void Quicksort(int S[],int low, int hi)
{
if (low < hi)
{
int p = partition(S,low,hi);
Quicksort(S,low,p-1);
Quicksort(S,p+1,hi);
}
}
You want the count_500++; outside the if statement. You're only counting the comparisons, where the result is true.
Change
if(S[i] < x)
{
count_500++; // Count the component wise comparison
...
}
to
count_500++; // Count the component wise comparison
if(S[i] < x)
{
...
}