Reputation: 15
I am writing an algorithm in C++ where the user types how many numbers they want to be sorted, then the program generates an array of random numbers, and sorts them. It also displays how much time it took to sort.
It only works for some of the trials, even if I use the same input. For example, if I ask the program to sort an array of 20 numbers, one of three things will happen:
Here is my partition algorithm (the thing giving me trouble). I am choosing the first/left item as my pivot:
int partition(int arr[], int leftIndex, int rightIndex)
{
int i = leftIndex;
int j = rightIndex;
int pivotValue = arr[leftIndex];
while(i < j){
while(arr[i] <= pivotValue){
i++;
}
while(arr[j] > pivotValue && i < j){
j--;
}
if(i < j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i - 1];
arr[i - 1] = arr[leftIndex];
arr[leftIndex] = temp;
return i - 1;
}
Here is my quicksort algorithm:
void quickSort(int arr[], int left, int right)
{
if (left < right)
{
int pivot = partition(arr, left, right);
quickSort(arr, left, pivot - 1);
quickSort(arr, pivot + 1, right);
}
return;
}
Here is where I call everything in main():
int main()
{
clock_t sTime, eTime;
int n;
cout << "Enter an array size: " << endl;
cin >> n;
cout << endl;
int originalArray[n];
cout << "Start generating random numbers..." << endl;
for(int index=0; index<n; index++){
originalArray[index] = (rand()%100)+1;
}
cout << "Original array values: ";
printArray(originalArray, n);
cout<<"\n\n";
//Makes a copy of the original array to preserve its original order
int quickArray[sizeof(originalArray)];
for(int i = 0; i < sizeof(originalArray); i++){
quickArray[i] = originalArray[i];
}
//Perform quicksort
sTime = clock();
quickSort(quickArray, 0, n-1);
eTime = clock();
printf("Sorted array by quickSort: ");
printArray(quickArray, n);
cout << "\nTotal CPU time used in quickSort: " << (double)(eTime-sTime) / CLOCKS_PER_SEC * 1000.0 << " ms" << endl;
cout << endl;
return 0;
}
Upvotes: 0
Views: 3174
Reputation: 2832
#include <bits/stdc++.h>
using namespace std;
int partition(int arr[], int leftIndex, int rightIndex)
{
int pivotIndex = leftIndex;
int pivotValue = arr[pivotIndex];
int i = leftIndex;
int j = rightIndex;
while(i < j){
while(arr[i] <= pivotValue){
i++;
if(i >= rightIndex) break;
}
while(arr[j] >= pivotValue){
j--;
if(j <= leftIndex) break;
}
if(i < j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// swap
arr[pivotIndex] = arr[j];
arr[j] = pivotValue;
return j;
}
void quickSort(int arr[], int left, int right)
{
if (left < right)
{
int pivot = partition(arr, left, right);
quickSort(arr, left, pivot - 1);
quickSort(arr, pivot + 1, right);
}
return;
}
int main()
{
clock_t sTime, eTime;
int n;
cout << "Enter an array size: " << endl;
cin >> n;
cout << endl;
int originalArray[n];
cout << "Start generating random numbers..." << endl;
for(int index=0; index<n; index++){
originalArray[index] = (rand()%100)+1;
}
cout << "Original array values: ";
for(auto c: originalArray) {
cout << c << " ";
}
cout<<"\n\n";
//Makes a copy of the original array to preserve its original order
int quickArray[n];
for(int i = 0; i < n; i++){
quickArray[i] = originalArray[i];
}
//Perform quicksort
sTime = clock();
quickSort(quickArray, 0, n-1);
eTime = clock();
printf("Sorted array by quickSort: ");
for(auto c: quickArray) {
cout << c << " ";
}
cout << endl;
cout << "\nTotal CPU time used in quickSort: " << (double)(eTime-sTime) / CLOCKS_PER_SEC * 1000.0 << " ms" << endl;
cout << endl;
return 0;
}
There were several mistakes I've encountered. Firstly, I have added break
statements in the while loops of partititon()
method so that it breaks incrementing i
or decrementing j
if they exceeds the boundaries of the array. That was probably why you get segmentation fault sometimes.
Then I've changed the swapping part at the end of the partition and returned j
. Probably this part was not erroneous, but I find this solution to be more readable.
Then I changed the part where you create the new array to int quickArray[n]
, you were creating the quickArray
with sizeof(originalArray)
, which was wrong because it used to create an array with more elements. sizeof()
returns (number of elements) * 4
since each int
takes 4 bytes of memory.
Now, it should be working properly.
In addition, picking the first element as pivot can make your program work in O(n^2)
time complexity in the worst case, try shuffling your array before sending it to the quicksort()
function. By doing so, you can eliminate the worst case scenario.
Upvotes: 1
Reputation: 490018
I'm not sure if it's responsible for all the problems you're seeing, but I'd start with this bit of code:
while(i < j){
while(arr[i] <= pivotValue){
i++;
}
What's this (especially the inner loop) going to do if the pivot is the largest value in the array?
Upvotes: 1