#include <iostream>
#include <cstdlib>
using namespace std;
void print(int a[], int sz)
{
for (int i = 0; i < sz; i++) cout << a[i] << " ";
cout << endl;
}
void merge(int a[], const int low, const int mid, const int high)
{
int *temp = new int[high-low+1];
int left = low;
int right = mid+1;
int current = 0;
// Merges the two arrays into temp[]
while(left <= mid && right <= high)
{
if(a[left] <= a[right])
{
temp[current] = a[left];
left++;
}
else { // if right element is smaller that the left
{
// if right element is smaller that the left
temp[current] = a[right];
right++;
}
current++;
}
// Fills the array
// The temp array has already been filled
// Use the right side of array to fill temp
if(left > mid)
{
for(int i=right; i <= high;i++)
{
temp[current] = a[i];
current++;
}
}
// Use the left side of array to fill temp
else
{
for(int i=left; i <= mid; i++)
{
temp[current] = a[i];
current++;
}
}
//Fill into original array
for(int i=0; i<=high-low;i++)
{
a[i+low] = temp[i];
}
delete[] temp;
}
void merge_sort(int a[], const int low, const int high)
{ // <-- Error #68
if(low >= high) return;
int mid = (low+high)/2;
merge_sort(a, low, mid); //left half
merge_sort(a, mid+1, high); //right half
merge(a, low, mid, high); //merge them
}
int main()
{ //<-- Error #77
int a[] = {26, 5, 33, 6, 19, 69, 99};
int arraySize = sizeof(a)/sizeof(int);
print(a, arraySize);
merge_sort(a, 0, (arraySize-1));
print(a, arraySize);
return 0;
} //<-- Error #87
// This code is supposed to implement the Merge sort algorithm in c++.
However when ever i compile my code it runs into a bunch of errors.
mergesort.cpp: In function ‘void merge(int*, int, int, int)’:
mergesort.cpp:68: error: a function-definition is not allowed here before ‘{’ token
mergesort.cpp:77: error: a function-definition is not allowed here before ‘{’ token
mergesort.cpp:87: error: expected ‘}’ at end of input
I have indicated where the erros are in the code
Can anyone help me please?
#include <iostream>
#include <cstdlib>
using namespace std;
void print(int a[], int sz)
{
for (int i = 0; i < sz; i++) cout << a[i] << " ";
cout << endl;
}
void merge(int a[], const int low, const int mid, const int high)
{
int *temp = new int[high-low+1];
int left = low;
int right = mid+1;
int current = 0;
// Merges the two arrays into temp[]
while(left <= mid && right <= high)
{
if(a[left] <= a[right])
{
temp[current] = a[left];
left++;
}
else
{
// if right element is smaller that the left
temp[current] = a[right];
right++;
}
current++;
}
// Fills the array
// The temp array has already been filled
// Use the right side of array to fill temp
if(left > mid)
{
for(int i=right; i <= high;i++)
{
temp[current] = a[i];
current++;
}
}
// Use the left side of array to fill temp
else
{
for(int i=left; i <= mid; i++)
{
temp[current] = a[i];
current++;
}
}
//Fill into original array
for(int i=0; i<=high-low;i++)
{
a[i+low] = temp[i];
}
delete[] temp;
}
void merge_sort(int a[], const int low, const int high)
{
if(low >= high) return;
int mid = (low+high)/2;
merge_sort(a, low, mid); //left half
merge_sort(a, mid+1, high); //right half
merge(a, low, mid, high); //merge them
}
main()
{
int a[] = {26, 5, 33, 6, 19, 69, 99};
int arraySize = sizeof(a)/sizeof(int);
print(a, arraySize);
merge_sort(a, 0, (arraySize-1));
print(a, arraySize);
}
You are getting this error because you write an extra { on line 27, which will mess up all those { } matching.
Delete that you will pass the compile.
Hope this helps.
Related
Here is the pseudocode straight from the book (CORMEN):
Partition(A,p,r)
x=A[p]
i=p-1
j=r+1
while(TRUE)
repeat
j=j-1
until A[j]<=x
repeat
i=i+1
until A[i]>=x
if i<j
SWAP A[i] <=> A[j]
else return j
Here is code in C++:
#include<bits/stdc++.h>
using namespace std;
int partition(int a[], int low, int high)
{
int pivot = a[low];
int i = low - 1;
int j = high + 1;
while (1)
{
do {
i++;
} while (a[i] < pivot);
do {
j--;
} while (a[j] > pivot);
if (i >= j) {
cout<<j<<endl;
return j;
}
swap(a[i], a[j]);
}
}
/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[p] is now
at right place*/
int pi = partition(arr, low, high);
// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
// Driver program to test above functions
int main()
{
int arr[] = {7,3,2,6,4,1,3,5};
int n = sizeof(arr)/sizeof(arr[0]);
cout<<"partition:\n";
partition(arr,0,7);
printArray(arr, n);
quickSort(arr, 0, n-1);
printf("Sorted array: \n");
printArray(arr, n);
return 0;
}
If I use this array in input:
[5,3,2,6,4,1,3,7]
everything works logically well because the array returned by the partitioning will be:
[3,3,2,1,4,6,5,7]
Termination i=5 and j=4 so my pivot is 4. And all elements to the left of 4 are minor and all to the right are major
Now if I use this array in input:
[7,3,2,6,4,1,3,5]
I will have this situation at the end of the partition
[5,3,2,6,4,1,3,7]
which will return to me as pivot j = 6 that is 3. Now the elements on the left of 3 are not all minor and on the right are major.
But how is it possible that this works? Shouldn't I have the elements to the left of the pivot minor and to the right major?
With Hoare partition the pivot and values equal to the pivot can end up anywhere. The returned index is not an index to the pivot, but just a separator. For the code above, when partition is done, then elements <= pivot will be at or to the left of j, and elements >= pivot will be to the right of j. After doing a partition step, the C++ code should be:
quickSort(arr, low, pi); // not pi - 1
quickSort(arr, pi + 1, high);
example code that includes testing of quicksort:
uint32_t Rnd32()
{
static uint32_t r = 0;
r = r*1664525 + 1013904223;
return r;
}
int Partition(int ar[], int lo, int hi)
{
int pv = ar[lo+(hi-lo)/2];
int i = lo - 1;
int j = hi + 1;
while(1){
while(ar[++i] < pv);
while(ar[--j] > pv);
if(i >= j)
return j;
std::swap(ar[i], ar[j]);
}
}
void QuickSort(int ar[], int lo, int hi)
{
while (lo < hi){
int pi = Partition(ar, lo, hi);
if((pi - lo) < (pi - hi)){
QuickSort(ar, lo, pi);
lo = pi + 1;
} else {
QuickSort(ar, pi + 1, hi);
hi = pi;
}
}
}
#define COUNT (16*1024*1024)
int main(int argc, char**argv)
{
size_t i;
int * ar = new int [COUNT];
for(i = 0; i < COUNT; i++){
ar[i] = Rnd32();
}
QuickSort(ar, 0, COUNT-1);
for(i = 1; i < COUNT; i++)
if(ar[i-1] > ar[i])
break;
if(i == COUNT)
std::cout << "passed" << std::endl;
else
std::cout << "failed" << std::endl;
delete[] ar;
return(0);
}
Working on a class project in which i need to implement a Merge Sort to sort 500,000 items.
After many attempts I tried looking for source code online and found some here: http://www.sanfoundry.com/cpp-program-implement-merge-sort/
I had to alter the code to use a dynamic array (for size). When the program runs the merge function, I create a new, dynamic array using the number of elements (or high) that are being merged. Once the function is finished sorting them and merge them into the original array, i use delete[] on the new dynamic array. This is where I get my "Heap Corruption Detected" error.
Here is the code (wall of text):
//Heap Sort
#include <iostream>
#include <fstream>
#include <sstream>
#include <ctime>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
//Function Prototypes
void mergesort(int *a, int low, int high);
void merge(int *a, int low, int high, int mid);
int main()
{
//Start with element 1 of the array
int line_no = 0;
int num;
int array_size = 500000;
int* num_array = new int[array_size];
//Open file for input
fstream in_file("CSCI3380_final_project_dataset.txt", ios::in);
//Test for file opening
if (!in_file)
{
cout << "Cannot open words1.txt for reading" << endl;
exit(-1);
}
//Read file
while(true)
{
//Read one line at a time
in_file >> num;
//Test for eof
if (in_file.eof())
break;
num_array[line_no] = num;
//Increment array position
line_no++;
}
//Close the file
in_file.close();
//Start Time
clock_t time_a = clock();
//Run Sorting Algorithim
mergesort(num_array, 0, array_size-1);
//End Time
clock_t time_b = clock();
//Elapsed Time
if (time_a == ((clock_t)-1) || time_b == ((clock_t)-1))
{
cout << "Unable to calculate elapsed time" << endl;
}
else
{
int total_time_ticks = time_b - time_a;
cout << "Elapsed time: " << total_time_ticks << endl;
}
delete[] num_array;
return 0;
}
void mergesort(int *a, int low, int high)
{
int mid;
if (low < high)
{
mid=(low+high)/2;
mergesort(a,low,mid);
mergesort(a,mid+1,high);
merge(a,low,high,mid);
}
return;
}
void merge(int *a, int low, int high, int mid)
{
//--------------------------Create new array-------------------------------
int* sort_array = new int[high];
//--------------------------New Array Created-----------------------------
int i, j, k;
i = low;
k = low;
j = mid + 1;
while (i <= mid && j <= high)
{
if (a[i] < a[j])
{
sort_array[k] = a[i];
k++;
i++;
}
else
{
sort_array[k] = a[j];
k++;
j++;
}
}
while (i <= mid)
{
sort_array[k] = a[i];
k++;
i++;
}
while (j <= high)
{
sort_array[k] = a[j];
k++;
j++;
}
for (i = low; i < k; i++)
{
a[i] = sort_array[i];
}
//---------------------------Delete the New Array--------------------
delete[] sort_array;
//--------------------------Oh No! Heap Corruption!------------------
}
I'll spare you the "you should be using vectors", "you should be using smart pointers", etc. You should be, and I'll leave it at that. Regarding your actual problem....
You're writing one-past the allocated space of your array. The allocated size is high:
int* sort_array = new int[high];
meaning you can only dereference from 0..(high-1). Yet this:
while (j <= high)
{
sort_array[k] = a[j];
k++;
j++;
}
is one location that is guaranteed to write to sort_array[high], and therefore invoke undefined behavior.
A Different Approach
Mergesort is about div-2 partitioning. You know this. What you may not have considered is that C and C++ both perform pointer-arithmetic beautifully and as such you only need two parameters for mergesort(): a base address and a length. the rest can be taken care of for you with pointer math:
Consider this:
void mergesort(int *a, int len)
{
if (len < 2)
return;
int mid = len/2;
mergesort(a, mid);
mergesort(a + mid, len-mid);
merge(a, mid, len);
}
And a merge implementation that looks like this:
void merge(int *a, int mid, int len)
{
int *sort_array = new int[ len ];
int i=0, j=mid, k=0;
while (i < mid && j < len)
{
if (a[i] < a[j])
sort_array[k++] = a[i++];
else
sort_array[k++] = a[j++];
}
while (i < mid)
sort_array[k++] = a[i++];
while (j < len)
sort_array[k++] = a[j++];
for (i=0;i<len;++i)
a[i] = sort_array[i];
delete[] sort_array;
}
Invoked from main() like the following. Note: I've removed the file i/o in place of a random generation just to make it easier to test:
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cstdio>
using namespace std;
//Function Prototypes
void mergesort(int *a, int len);
void merge(int *a, int mid, int len);
int main()
{
std::srand((unsigned int)std::time(nullptr));
// Start with element 1 of the array
int array_size = 500000;
int* num_array = new int[array_size];
std::generate_n(num_array, array_size, std::rand);
// Start Time
clock_t time_a = clock();
// Run Sorting Algorithim
mergesort(num_array, array_size);
// End Time
clock_t time_b = clock();
//Elapsed Time
if (time_a == ((clock_t)-1) || time_b == ((clock_t)-1))
{
cout << "Unable to calculate elapsed time" << endl;
}
else
{
int total_time_ticks = time_b - time_a;
cout << "Elapsed time: " << total_time_ticks << endl;
}
delete[] num_array;
return 0;
}
This resulted is an elapsed time of:
Elapsed time: 247287
More Efficient
By now you've seen that you will need at most N-space in addition to you sequence. The top-most merge should e evidence enough of that. What you may not consider is that in-reality that is exactly the space you need, and you can allocate it up-front and use it throughout the algorithm if you desire. You can keep the current entrapping for mergesort(), but we'll be wrapping it up with a front-loader that allocates all the space we'll ever need once:
// merges the two sequences a[0...mid-1] and a[mid...len-1]
// using tmp[] as the temporary storage space
static void merge_s(int *a, int *tmp, int mid, int len)
{
int i=0, j=mid, k=0;
while (i < mid && j < len)
{
if (a[i] < a[j])
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}
while (i < mid)
tmp[k++] = a[i++];
while (j < len)
tmp[k++] = a[j++];
for (i=0;i<len;++i)
a[i] = tmp[i];
}
static void mergesort_s(int *a, int *tmp, int len)
{
if (len < 2)
return;
int mid = len/2;
mergesort_s(a, tmp, mid);
mergesort_s(a + mid, tmp+mid, len-mid);
merge_s(a, tmp, mid, len);
}
void mergesort(int *a, int len)
{
if (len < 2)
return;
int *tmp = new int[len];
mergesort_s(a,tmp,len);
delete [] tmp;
}
This resulted in an elapsed time of:
Elapsed time: 164704
Considerably better than we had before. Best of luck.
The copy step shown in WhozCraig's code example can be avoided using a pair of functions to control the direction of the merge (note - a bottom up merge would still be faster).
Note - I wouldn't recommend using either WhozCraig's or my code example, since these methods were probably not covered in your class, and it's supposed to be code written based on what you were taught in your class. I don't know if bottom up merge sort was covered in your class, so I didn't post an example of it.
mergesort_s(int *a, int *tmp, int len)
{
// ...
mergesort_atoa(a, tmp, 0, len);
// ...
}
mergesort_atoa(int *a, int *tmp, int low, int end)
{
if((end - low) < 2){
return;
}
int mid = (low + end) / 2;
mergesort_atot(a, tmp, low, mid);
mergesort_atot(a, tmp, mid, end);
merge_s(tmp, a, low, mid, end);
}
mergesort_atot(int *a, int *tmp, int low, int end)
{
if((end - low) < 2){
tmp[0] = a[0];
return;
}
int mid = (low + end) / 2;
mergesort_atoa(a, tmp, low, mid);
mergesort_atoa(a, tmp, mid, end);
merge_s(a, tmp, low, mid, end);
}
void merge_s(int *src, int *dst, int low, int mid, int end)
{
int i = low; // src[] left index
int j = mid; // src[] right index
int k = low; // dst[] index
while(1){ // merge data
if(src[i] <= src[j]){ // if src[i] <= src[j]
dst[k++] = src[i++]; // copy src[i]
if(i < mid) // if not end of left run
continue; // continue (back to while)
while(j < end) // else copy rest of right run
dst[k++] = src[j++];
return; // and return
} else { // else src[i] > src[j]
dst[k++] = src[j++]; // copy src[j]
if(j < end) // if not end of right run
continue; // continue (back to while)
while(i < mid) // else copy rest of left run
dst[k++] = src[i++];
return; // and return
}
}
}
I'm trying to make a Mergesort function and can't seem to understand why my list is printing out "00000100000". I have a feeling it might be my auxiliary array that i'm passing through, but i'd like to keep it in my code if possible. Here is my code:
void merge(int arr[], int aux[], int low, int mid, int high)
{
int leftStart = low;
int rightStart = mid+1;
int auxIndex = low;
int start = low;
while(leftStart<=mid && rightStart<= high)
{
if(arr[leftStart]>=arr[rightStart])
{
aux[auxIndex] = arr[rightStart];
auxIndex++;
rightStart++;
}
else
aux[auxIndex] = arr[leftStart];
auxIndex++;
leftStart++;
}
if(leftStart>mid)
{
for(;rightStart<=high; rightStart++)
{
aux[auxIndex] = arr[rightStart];
}
}
if(rightStart>high)
{
for(;leftStart<=high; leftStart++)
{
aux[auxIndex] = arr[rightStart];
}
}
for(; start <= high; start++)
arr[start]=aux[start];
}
void mergeSort(int arr[], int aux[], int low, int high)
{
int mid;
if(low<high)
{
mid=(low+high)/2;
mergeSort(arr, aux, low, mid);
mergeSort(arr, aux, mid+1, high);
merge(arr,aux, low, mid, high);
}
}
int main(int argc, char *argv[]) {
int arr[20]={6,4,3,2,1,7,8,9,5,6,7,5};
for(int i = 0; i<12; i++)
cout<<arr[i];
int aux[20];
mergeSort(arr, aux, 0, 12);
for(int i = 0; i<12; i++)
cout<<arr[i];
return 0;
}
Run your program under valgrind or an equivalent analysis tool. You will find that there are straightforward errors in your code related to array accesses.
I am trying to implement Quick Sort algorithm. Following code works for unique elements but it doesn't working for arrays having duplicate elements. Please tell me where I am doing wrong. Also when I change value of pivot to some other number other than 0 , program crashes. Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
void swapme(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void quicksort(int *arr, int size)
{
// these two variables will take care of position of comparison
int lower = 0, upper = size - 1;
int pivot = 0; // assigns pivot
if (size <= 1)
return;
while (lower < upper)
{
while (arr[lower] < arr[pivot])
{
++lower;
}
}
while (arr[upper] > arr[pivot])
{
--upper;
}
if (upper > lower)
{
swapme(arr[upper], arr[lower]);
// upper--;
// lower++;
}
quicksort(arr, lower);
quicksort(&arr[lower + 1], size - 1 - lower);
}
int main()
{
int arr[30];
for(int j = 0; j < 30; j++)
{
arr[j] = 1 + rand() % 5000;
}
for(int j = 0; j < 30; j++)
{
cout << arr[j] << "\t";
}
cout << endl;
quicksort(arr, 30);
for(int j = 0; j < 30; j++)
{
cout << arr[j] << "\t";
}
cout << endl;
cin.get();
cin.get();
}
Update: I have finally managed to make it work. Here is the fixed version:
void swapme(int &a, int &b )
{
int temp = a;
a = b;
b = temp;
}
void quicksort(int *arr, int size)
{
if (size <= 1)
return;
// These two variables will take care of position of comparison.
int lower = 0;
int upper = size-1;
int pivot = arr[upper/2]; // assigns pivot
while (lower <= upper)
{
while (arr[lower] < pivot)
++lower;
while (arr[upper] > pivot)
--upper;
if (upper >= lower)
{
swapme(arr[upper],arr[lower]);
if(arr[upper] == arr[lower])
{
// Can either increment or decrement in case of duplicate entry
upper--; // lower++;
}
}
}
quicksort(arr, lower);
quicksort( &arr[lower+1], size-1-lower);
}
You are storing the index of your pivot element in the pivot variable, so swapping the elements can potentially change the choice of pivot element during the loop. Not a very good idea. I would suggest storing the actual value of the pivot element inside pivot instead.
Also, if this really isn't homework, why don't you simply use the standard library facilities?
#include <algorithm>
// ...
std::sort(arr + 0, arr + 30);
You will get heavily optimized and tested code that will outperform your handwritten Quicksort anytime.
Quick Sort that can implement any number of i/p integers. it also deal with duplicate keys
#include <conio.h>
#include <string>
using namespace std;
void InputArray(int*,int);
void QuickSort(int *,int,int);
int partition(int *,int,int);
void swap(int *,int,int);
void printArr(int *,int Siz=11);
void main(){
int siz;
cout<<"Enter Array length : "; cin>>siz;
int *a=new int[siz];
InputArray(a,siz);
QuickSort(a,0,siz-1);
int i=0,j=11;
printArr(a,siz);
system("pause");
}
void InputArray(int*a,int s){
for(int i=0; i<s; i++){
cout<<"ELement ["<<i<<"] = "; cin>>a[i];
}
}
void QuickSort(int *a,int start,int end){
if(start<end){
int pivot=partition(a,start,end);
QuickSort(a,start,pivot);
QuickSort(a,pivot+1,end);
}
}
int partition(int *a,int start,int end){
int currentPivotValue=a[start];
int i=start-1, j=end+1;
while(true){
i++;
while(i<j && a[i]<currentPivotValue){ i++; }
j--;
while(j>start && a[j]>currentPivotValue) {j--;}
if(i<j) swap(a,i,j);
else return j;
}
}
void swap(int *b,int i,int j){
int t=b[i];
b[i]=b[j];
b[j]=t;
}
void printArr(int *a,int Siz){
for(int i=0; i<Siz; i++) cout<<a[i]<<" ";
}
I'm not looking to copy a qsort algorithm. I'm practicing writing qsort and this is what I've come up with and I'm interested in what part of my code is wrong. Please don't tell me that this is homework cause I could just use the code in the link below.
Reference: http://xoax.net/comp/sci/algorithms/Lesson4.php
When this runs I get this in the console:
Program loaded.
run
[Switching to process 10738]
Running…
Current language: auto; currently c++
Program received signal: “EXC_ARITHMETIC”.
void myQSort(int min, int max, int* myArray)
{
// Initially find a random pivot
int pivotIndex = rand() % max;
int pivot = myArray[pivotIndex];
int i = 0 , j = max-1;
// Pointer to begining of array and one to the end
int* begin = myArray;
int* end = &myArray[max-1];
// While begin < end
while( begin < end )
{
// Find the lowest bound number to swap
while( *begin < pivot )
{
begin++;
}
while( *end > pivot )
{
// Find the highest bound number to swap
end--;
}
// Do the swap
swap(begin,end);
}
// Partition left
myQSort(0, pivotIndex-1, myArray);
// Partiion right
myQSort(pivotIndex+1,max, myArray);
}
EDIT--
Code for Swap:
void swap(int* num, int* num2)
{
int temp = *num;
*num = *num2;
*num2 = temp;
}
// sort interval [begin, end)
void myQSort(int* begin, int* end)
{
if(end - begin < 2)
return;
int* l = begin;
int* r = end - 1;
// Initially find a random pivot
int* pivot = l + rand() % (r - l + 1);
while(l != r)
{
// Find the lowest bound number to swap
while(*l < *pivot) ++l;
while(*r >= *pivot && l < r) --r;
// Do the swap
if(pivot == l) { pivot = r; }
std::swap(*l, *r);
}
// Here l == r and numbers in the interval [begin, r) are lower and in the interval [l, end) are greater or equal than the pivot
// Move pivot to the position
std::swap(*pivot, *l);
// Sort left
myQSort(begin, l);
// Sort right
myQSort(l + 1, end);
}
You're not using the min parameter in your code, anywhere. You need to set begin and your pivot value using that.
I tried working out the codes above. But, they don't compile.
#Mihran: Your solution is correct algorithmically but the following line generates an error:
myQSort(min, begin - myArray, myArray);
This is because begin is of type int* and myArray is of type long, following which the compiler shows this error message:
implicit conversion loses integer precision
Here's a working solution in C++:
#include <iostream>
using namespace std;
void mySwap(int& num1, int& num2){
int temp = num1;
num1 = num2;
num2 = temp;
}
void myQsort(int myArray[], int min, int max){
int pivot = myArray[(min + max) / 2];
int left = min, right = max;
while (left < right) {
while (myArray[left] < pivot) {
left++;
}
while (myArray[right] > pivot) {
right--;
}
if (left <= right) {
mySwap(myArray[left], myArray[right]);
left++;
right--;
}
}
if (min < right) {
myQsort(myArray, min, right);
}
if (left < max) {
myQsort(myArray, left, max);
}
}
int main()
{
int myArray[] = {1, 12, -5, 260, 7, 14, 3, 7, 2};
int min = 0;
int max = sizeof(myArray) / sizeof(int);
myQsort(myArray, min, max-1);
for (int i = 0; i < max; i++) {
cout<<myArray[i]<<" ";
}
return 0;
}
Here's a clear C++ implementation, for reference:
#include <iostream>
#include <vector>
using namespace std;
int partition(std::vector<int>& arr, int low, int high) {
// set wall index
int wall_index = low;
int curr_index = low;
int pivot_elem = arr[high]; // taking last element as pivot_element
// loop through the entire received arr
for (int i = curr_index; i < high; ++i) {
// if element is less than or equal to pivot_elem
// swap the element with element on the right of the wall
// i.e swap arr[i] with arr[wall_index]
if (arr[i] <= pivot_elem) {
// swap
int temp = arr[wall_index];
arr[wall_index] = arr[i];
arr[i] = temp;
// move the wall one index to the right
wall_index++;
curr_index++;
} else {
// if the element is greater than the pivot_element
// then keep the wall at the same point and do nothing
curr_index++;
}
}
// need to swap the pivot_elem i.e arr[high] with the element right of the wall
int temp = arr[wall_index];
arr[wall_index] = arr[high];
arr[high] = temp;
return wall_index;
}
void quick_sort(std::vector<int>& arr, int low, int high) {
if (low < high) { // element with single arr always have low >= high
int split = partition(arr, low, high);
quick_sort(arr, low, split-1);
quick_sort(arr, split, high);
}
}
int main() {
std::vector<int> data = {6,13,8,4,2,7,16,3,8};
int N = data.size();
quick_sort(data, 0, N-1);
for (int i : data) {
cout << i << " ";
}
return 0;
}
I don't see a clean implementation of Quicksort on SO, so here is my easy to understand implementation
PLEASE DONT USE IN PRODUCTION CODE
This is only for your understanding
// Swap position a with b in an array of integer numbers
void swap(int *numbers, int a, int b){
int temp = numbers[a];
numbers[a] = numbers[b];
numbers[b] = temp;
}
static int partition(int *data, int low, int high) {
int left = low, right = high, pivot = data[low];
while (left < right) {
// Everthing on the left of pivot is lower than the pivot
while ((left <= right) && data[left] <= pivot) // <= is because left is the pivot initially
left++;
// Everything on the right of the pivot is greater than the pivot
while((left <= right) && data[right] > pivot)
right--;
if (left < right)
swap(data, left, right);
}
// Put the pivot in the 'rigthful' place
swap(data, low, right);
return right;
}
// Quicksort
static void quick_sort(int *numbers, int low, int high)
{
if (high > low) {
int p_index = partition(numbers, low, high);
quick_sort(numbers, low , p_index - 1);
quick_sort(numbers, p_index + 1, high);
}
}