And comparing the speed of msort with both quick sorts ...
// qsorts_msort_ary_timed.cpp // note: msort is a 'stabile sort'
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int c1 = 0, c2 = 0; // globals ... for count of swaps ...
template< typename T > // from DIC KYA ...
int partition( T data[], int left, int right, int pivot )
{
int storeIndex = left;
T tmp, pivotVal = data[pivot];
data[pivot] = data[right];
data[right] = pivotVal;
for( int i = left; i < right; ++i )
{
if( data[i] <= pivotVal )
{
++c1; // count swaps ... (c1 is a global variable)
tmp = data[i];
data[i] = data[storeIndex];
data[storeIndex] = tmp;
storeIndex++;
}
}
++c1; // count swaps ...
tmp = data[storeIndex];
data[storeIndex] = data[right];
data[right] = tmp;
return storeIndex;
}
template< typename T > // from KYA at DIC ...
void qSort( T data[], int left, int right )
{
if( right > left )
{
int mid = ( left + right )/2;
int newPivot = partition( data, left, right, mid );
qSort( data, left, newPivot-1 );
qSort( data, newPivot+1, right );
}
}
// my quick sort ... (edited from a Comal version)
template< typename T >
void qSort2( T ary[], int left, int right )
{
int lft = left, rht = right;
T tmp, comp = ary[(lft+rht)/2];
do
{
while( ary[lft] < comp ) ++lft;
while( ary[rht] > comp ) --rht;
if( lft <= rht ) // swap ...
{
++c2; // count swaps ... (c2 is a global variable)
tmp = ary[lft];
ary[lft] = ary[rht];
ary[rht] = tmp;
++lft; --rht;
}
}while( lft <= rht );
if( left < rht ) qSort2( ary, left, rht);
if( lft < right ) qSort2( ary, lft, right);
}
// merge two adjacent ranges in array ary ...
template< typename T >
void merge( T ary[], size_t bot, size_t mid, size_t top, T tmp[] )
{
size_t sz = top - bot + 1; // size of the range to be merged
//T* tmp = new T[ sz ]; // merge both halves into array tmp
size_t j = 0; // next open index in tmp
size_t h1 = bot; // next index to consider in the 1st half
size_t h2 = mid + 1; // next index to consider in the 2nd half
// while indexes h1 and h2 are not past their ends ...
while( h1 <= mid && h2 <= top )
{ // move the smaller element into the tmp array ...
if( ary[h1] < ary[h2] ) tmp[j++] = ary[h1++];
else tmp[j++] = ary[h2++];
}
// Note: only one of the two while loops below is executed ...
while( h1 <= mid ) tmp[j++] = ary[h1++]; // copy any remaining entries (1st half)
while( h2 <= top ) tmp[j++] = ary[h2++]; // copy any remaining entries (2nd half)
for( j = 0; j < sz; ++j ) ary[bot+j] = tmp[j]; // copy back sorted tmp array
//delete [] tmp;
}
// merge sort elements in array ary in range ...
template< typename T >
void my_msort( T ary[], size_t bot, size_t top, T tmp[] )
{
if( bot == top ) return;
size_t mid = ( bot + top ) / 2;
my_msort( ary, bot, mid, tmp ); // sort the first ...
my_msort( ary, mid + 1, top, tmp ); // and the second half ...
merge( ary, bot, mid, top, tmp ); // now merge these 2 sorted chunks ...
}
// my_msort 'wrapper' speeds up merges (reduces all the new..deletes to just 1)
template< typename T >
void msort( T ary[], size_t bot, size_t top )
{
T* tmp = new T[top-bot+1];
my_msort( ary, bot, top, tmp );
delete [] tmp;
}
template< typename T >
void print( T ary[], int size )
{
for( int i = 0; i < size; ++i ) cout << setw(8) << ary[i];
cout << endl;
}
template< typename T >
string isSortedUp( T ary[], int size )
{
for( int i = size-1; i > 0; --i )
if( ary[i-1] > ary[i] ) return "Array is NOT sorted UP!";
// else ...
return "Array is sorted UP!";
}
int myIntCompare( const void* x, const void* y )
{
return *(int*)x - *(int*)y;
}
const int NUM = 3;
int main()
{
cout << setprecision(3) << fixed;
srand( unsigned(time(0)) ); // seed random number generator ...
double st1 =0, st2 =0, st3 =0; // to hold sumTime1 and sumTime2 ...
int num = NUM; // number of loops ...to count down
do
{
int size_d = 3000000; // size of array of random int's
int *d = new int[size_d];
int *e = new int[size_d];
int *f = new int[size_d]; // 3 copies of an unsorted array of int's
for( int i = 0; i < size_d; ++i ) d[i] = e[i] = f[i] = rand();
cout << "\nUnsorted: \t";
//print( d, size_d );
double t1 = clock();
qSort( d, 0, size_d-1 );
double t2 = clock() - t1;
st1 += t2;
cout << "\ttime to qSort was " << t2/CLOCKS_PER_SEC << " seconds "
<< isSortedUp( d, size_d ) << endl;
//print( d, size_d );
cout << "Unsorted: \t";
//print( e, size_d );
t1 = clock();
qSort2( e, 0, size_d-1 );
t2 = clock() - t1;
st2 += t2;
cout << "\ttime to qSort2 was " << t2/CLOCKS_PER_SEC << " seconds "
<< isSortedUp( e, size_d ) << endl;
//print( e, size_d );
cout << "Unsorted: \t";
//print( f, size_d );
t1 = clock();
msort( f, 0, size_d-1 );
t2 = clock() - t1;
st3 += t2;
cout << "\ttime to msort was " << t2/CLOCKS_PER_SEC << " seconds "
<< isSortedUp( f, size_d ) << endl;
//print( f, size_d );
delete [] f;
delete [] e;
delete [] d;
}
while( --num );
cout << "\nqSort swaps = " << c1
<< "\nqSort2 swaps = " << c2 << endl
<< "\nqSort time = " << st1/CLOCKS_PER_SEC/NUM
<< "\nqSort2 time = " << st2/CLOCKS_PER_SEC/NUM
<< "\nmsort time = " << st3/CLOCKS_PER_SEC/NUM << endl;
cout << "\nPress 'Enter' to continue ... " << flush;
cin.get();
}
// compiled under Dev C++ 4.9.9.2 ... my output ...
/*
Unsorted: time to qSort was 3.031 seconds Array is sorted UP!
Unsorted: time to qSort2 was 0.906 seconds Array is sorted UP!
Unsorted: time to msort was 1.531 seconds Array is sorted UP!
Unsorted: time to qSort was 2.922 seconds Array is sorted UP!
Unsorted: time to qSort2 was 0.875 seconds Array is sorted UP!
Unsorted: time to msort was 1.781 seconds Array is sorted UP!
Unsorted: time to qSort was 2.938 seconds Array is sorted UP!
Unsorted: time to qSort2 was 0.875 seconds Array is sorted UP!
Unsorted: time to msort was 1.562 seconds Array is sorted UP!
qSort swaps = 512520766
qSort2 swaps = 58308594
qSort time = 2.964
qSort2 time = 0.885
msort time = 1.625
Press 'Enter' to continue ...
*/
// compiled under VC++ 2008 ... my output ...
Unsorted: time to qSort was 3.343 seconds Array is sorted UP!
Unsorted: time to qSort2 was 1.000 seconds Array is sorted UP!
Unsorted: time to msort was 2.610 seconds Array is sorted UP!
Unsorted: time to qSort was 3.532 seconds Array is sorted UP!
Unsorted: time to qSort2 was 0.907 seconds Array is sorted UP!
Unsorted: time to msort was 2.063 seconds Array is sorted UP!
Unsorted: time to qSort was 3.015 seconds Array is sorted UP!
Unsorted: time to qSort2 was 0.891 seconds Array is sorted UP!
Unsorted: time to msort was 2.078 seconds Array is sorted UP!
qSort swaps = 510006044
qSort2 swaps = 58236424
qSort time = 3.297
qSort2 time = 0.933
msort time = 2.250
Press 'Enter' to continue ...
*/
Now ... comparing the speeds of 'qSort2', C's qsort and 'msort' ...
(of arrays that are random generated or pre-sorted ascending or descending)
// qSort2_qsort_msort_ary_timed.cpp
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib> // re. rand ...
#include <ctime> // re. time ...
using namespace std;
// my quick sort ... (edited from an old Comal version)
template< typename T >
void qSort2( T ary[], int left, int right )
{
int lft = left, rht = right;
T tmp, comp = ary[(lft+rht)/2];
do
{
while( ary[lft] < comp ) ++lft;
while( ary[rht] > comp ) --rht;
if( lft <= rht ) // swap ...
{
tmp = ary[lft];
ary[lft] = ary[rht];
ary[rht] = tmp;
++lft; --rht;
}
}while( lft <= rht );
if( left < rht ) qSort2( ary, left, rht);
if( lft < right ) qSort2( ary, lft, right);
}
// merge two adjacent ranges in array ary ...
template< typename T >
void merge( T ary[], size_t bot, size_t mid, size_t top, T tmp[] )
{
size_t sz = top - bot + 1; // size of the range to be merged
size_t j = 0; // next open index in tmp
size_t h1 = bot; // next index to consider in the 1st half
size_t h2 = mid + 1; // next index to consider in the 2nd half
// while indexes h1 and h2 are not past their ends ...
while( h1 <= mid && h2 <= top )
{ // move the smaller element into the tmp array ...
if( ary[h1] < ary[h2] ) tmp[j++] = ary[h1++];
else tmp[j++] = ary[h2++];
}
// Note: only one of the two while loops below is executed ...
while( h1 <= mid ) tmp[j++] = ary[h1++]; // copy any remaining entries (1st half)
while( h2 <= top ) tmp[j++] = ary[h2++]; // copy any remaining entries (2nd half)
for( j = 0; j < sz; ++j ) ary[bot+j] = tmp[j]; // copy back sorted tmp array
}
// merge sort elements in array ary in range ...
template< typename T >
void my_msort( T ary[], size_t bot, size_t top, T tmp[] )
{
if( bot == top ) return;
size_t mid = ( bot + top ) / 2;
my_msort( ary, bot, mid, tmp ); // sort the first ...
my_msort( ary, mid + 1, top, tmp ); // and the second half ...
merge( ary, bot, mid, top, tmp ); // now merge these 2 sorted chunks ...
}
// my_msort 'wrapper' speeds up merges (reduces all the new..deletes to just 1)
template< typename T >
void msort( T ary[], size_t bot, size_t top )
{
T* tmp = new T[top-bot+1];
my_msort( ary, bot, top, tmp );
delete [] tmp;
}
template< typename T >
bool isSortedUp( T ary[], int size )
{
for( int i = size-1; i > 0; --i )
if( ary[i-1] > ary[i] ) return false;
// else ...
return true;
}
template< typename T >
bool isSortedDn( T ary[], int size )
{
for( int i = size-1; i > 0; --i )
if( ary[i-1] < ary[i] ) return false;
// else ...
return true;
}
// for C's qsort ...
int myIntCompare( const void* x, const void* y )
{
return *(int*)x - *(int*)y;
}
// for C's qsort ... descending order ...
int myIntCompareRev( const void* x, const void* y )
{
return *(int*)y - *(int*)x;
}
bool fillFromFile( int d[], int e[], int f[], int size_d )
{
ifstream fin( "randInt3M.txt" );
if( !fin ) return false;
int i =0;
while( i < size_d && fin >> d[i] ) { f[i] = e[i] = d[i]; ++i; }
fin.close();
if( i == size_d ) return true;
else { cout << "Error filling int array's ..." << endl; return false; }
}
void writeFile( int ary[], int size )
{
ofstream fout( "randInt3M.txt" );
for( int i = 0, j = 0; i < size; ++i )
{
fout << ary[i] << " ";
if( ++j == 16 ) { j = 0; fout << endl; }
}
fout << endl;
fout.close();
}
const int BIGNUM = 3000000;
const int NUM = 3;
int main()
{
cout << setprecision(3) << fixed; // show 3 decimal places ...
srand( unsigned( time(0) )); // seed random number generator ...
double st[7] = {0}; // to hold sumTime[0]..sumTime[6]
int num = NUM; // number of loops ...to count down
do
{
int size_d = BIGNUM; // size of array of random int's
int *d = new int[size_d];
int *e = new int[size_d];
int *f = new int[size_d]; // get 3 copies of an unsorted array of int's
if( !fillFromFile( d, e, f, size_d ) )
{
srand( (unsigned) time(0) );
for( int i = 0; i < size_d; ++i ) f[i]=e[i]=d[i]=rand(); // fill arrays
writeFile( d, size_d );
}
cout << "\nUnsorted: \t";
double t1 = clock();
qSort2( d, 0, size_d-1 );
double t2 = clock() - t1;
st[0] += t2;
cout << " time to qSort2 was " << t2/CLOCKS_PER_SEC << " seconds ";
cout << "isSortedUp( d, size_d ) = " << isSortedUp( d, size_d ) << endl;
cout << "Unsorted: \t";
t1 = clock();
qsort( e, size_d, sizeof(int), myIntCompare );
t2 = clock() - t1;
st[1] += t2;
cout << " time to qsort was " << t2/CLOCKS_PER_SEC << " seconds ";
cout << "isSortedUp( e, size_d ) = " << isSortedUp( e, size_d ) << endl;
cout << "Pre. sorted: \t"; // was pre-sorted ...
t1 = clock();
qsort( e, size_d, sizeof(int), myIntCompare );
t2 = clock() - t1;
st[2] += t2;
cout << " time to qsort was " << t2/CLOCKS_PER_SEC << " seconds ";
cout << "isSortedUp( e, size_d ) = " << isSortedUp( e, size_d ) << endl;
cout << "Rev. sorted: \t"; // e was pre-sorted ... now will rev. sort
t1 = clock();
qsort( e, size_d, sizeof(int), myIntCompareRev );
t2 = clock() - t1;
st[3] += t2;
cout << " time to qsort was " << t2/CLOCKS_PER_SEC << " seconds ";
cout << "isSortedDn( e, size_d ) = " << isSortedDn( e, size_d ) << endl;
cout << "Unsorted: \t";
t1 = clock();
msort( f, 0, size_d-1 );
t2 = clock() - t1;
st[4] += t2;
cout << " time to msort was " << t2/CLOCKS_PER_SEC << " seconds ";
cout << "isSortedUp( f, size_d ) = " << isSortedUp( f, size_d ) << endl;
cout << "Pre. sorted: \t"; // was pre-sorted ...
t1 = clock();
msort( f, 0, size_d-1 );
t2 = clock() - t1;
st[5] += t2;
cout << " time to msort was " << t2/CLOCKS_PER_SEC << " seconds ";
cout << "isSortedUp( f, size_d ) = " << isSortedUp( f, size_d ) << endl;
cout << "Rev. sorted: \t"; // e was pre-sorted descending, now will sort
t1 = clock();
msort( e, 0, size_d-1 );
t2 = clock() - t1;
st[6] += t2;
cout << " time to msort was " << t2/CLOCKS_PER_SEC << " seconds ";
cout << "isSortedUp( e, size_d ) = " << isSortedUp( e, size_d ) << endl;
delete [] f;
delete [] e;
delete [] d;
}
while( --num );
cout << "\nqSort2 time = " << st[0]/CLOCKS_PER_SEC/NUM << endl
<< "\nqsort time = " << st[1]/CLOCKS_PER_SEC/NUM
<< "\nqsortPrtime = " << st[2]/CLOCKS_PER_SEC/NUM
<< "\nqsortRvtime = " << st[3]/CLOCKS_PER_SEC/NUM << endl
<< "\nmsort time = " << st[4]/CLOCKS_PER_SEC/NUM
<< "\nmsortPrtime = " << st[5]/CLOCKS_PER_SEC/NUM
<< "\nmsortRvtime = " << st[6]/CLOCKS_PER_SEC/NUM << endl;
cout << "\nPress 'Enter' to continue ... " << flush;
cin.get();
}
// compiled under Dev C++ 4.9.9.2 ... my output ...
/*
Unsorted: time to qSort2 was 0.844 seconds isSortedUp( d, size_d ) = 1
Unsorted: time to qsort was 0.890 seconds isSortedUp( e, size_d ) = 1
Pre. sorted: time to qsort was 0.344 seconds isSortedUp( e, size_d ) = 1
Rev. sorted: time to qsort was 0.391 seconds isSortedDn( e, size_d ) = 1
Unsorted: time to msort was 1.546 seconds isSortedUp( f, size_d ) = 1
Pre. sorted: time to msort was 1.219 seconds isSortedUp( f, size_d ) = 1
Rev. sorted: time to msort was 1.172 seconds isSortedUp( e, size_d ) = 1
Unsorted: time to qSort2 was 0.969 seconds isSortedUp( d, size_d ) = 1
Unsorted: time to qsort was 0.969 seconds isSortedUp( e, size_d ) = 1
Pre. sorted: time to qsort was 0.343 seconds isSortedUp( e, size_d ) = 1
Rev. sorted: time to qsort was 0.500 seconds isSortedDn( e, size_d ) = 1
Unsorted: time to msort was 1.578 seconds isSortedUp( f, size_d ) = 1
Pre. sorted: time to msort was 1.235 seconds isSortedUp( f, size_d ) = 1
Rev. sorted: time to msort was 1.203 seconds isSortedUp( e, size_d ) = 1
Unsorted: time to qSort2 was 0.843 seconds isSortedUp( d, size_d ) = 1
Unsorted: time to qsort was 0.859 seconds isSortedUp( e, size_d ) = 1
Pre. sorted: time to qsort was 0.359 seconds isSortedUp( e, size_d ) = 1
Rev. sorted: time to qsort was 0.375 seconds isSortedDn( e, size_d ) = 1
Unsorted: time to msort was 1.546 seconds isSortedUp( f, size_d ) = 1
Pre. sorted: time to msort was 1.234 seconds isSortedUp( f, size_d ) = 1
Rev. sorted: time to msort was 1.188 seconds isSortedUp( e, size_d ) = 1
qSort2 time = 0.885
qsort time = 0.906
qsortPrtime = 0.349
qsortRvtime = 0.422
msort time = 1.557
msortPrtime = 1.229
msortRvtime = 1.188
Press 'Enter' to continue ...
*/
// compiled under VC++ 2008 ... my output ...
/*
Unsorted: time to qSort2 was 0.875 seconds isSortedUp( d, size_d ) = 1
Unsorted: time to qsort was 4.422 seconds isSortedUp( e, size_d ) = 1
Pre. sorted: time to qsort was 2.859 seconds isSortedUp( e, size_d ) = 1
Rev. sorted: time to qsort was 2.922 seconds isSortedDn( e, size_d ) = 1
Unsorted: time to msort was 2.078 seconds isSortedUp( f, size_d ) = 1
Pre. sorted: time to msort was 1.703 seconds isSortedUp( f, size_d ) = 1
Rev. sorted: time to msort was 1.641 seconds isSortedUp( e, size_d ) = 1
Unsorted: time to qSort2 was 0.875 seconds isSortedUp( d, size_d ) = 1
Unsorted: time to qsort was 4.406 seconds isSortedUp( e, size_d ) = 1
Pre. sorted: time to qsort was 2.843 seconds isSortedUp( e, size_d ) = 1
Rev. sorted: time to qsort was 2.921 seconds isSortedDn( e, size_d ) = 1
Unsorted: time to msort was 2.063 seconds isSortedUp( f, size_d ) = 1
Pre. sorted: time to msort was 1.703 seconds isSortedUp( f, size_d ) = 1
Rev. sorted: time to msort was 1.625 seconds isSortedUp( e, size_d ) = 1
Unsorted: time to qSort2 was 0.875 seconds isSortedUp( d, size_d ) = 1
Unsorted: time to qsort was 4.453 seconds isSortedUp( e, size_d ) = 1
Pre. sorted: time to qsort was 2.860 seconds isSortedUp( e, size_d ) = 1
Rev. sorted: time to qsort was 2.922 seconds isSortedDn( e, size_d ) = 1
Unsorted: time to msort was 2.063 seconds isSortedUp( f, size_d ) = 1
Pre. sorted: time to msort was 1.688 seconds isSortedUp( f, size_d ) = 1
Rev. sorted: time to msort was 1.641 seconds isSortedUp( e, size_d ) = 1
qSort2 time = 0.875
qsort time = 4.427
qsortPrtime = 2.854
qsortRvtime = 2.922
msort time = 2.068
msortPrtime = 1.698
msortRvtime = 1.636
Press 'Enter' to continue ...
*/