EDIT (changes) (code posted)
- Ended up re-writing merge_sort
- Removed merge_sort and quick_sort and created separate classes
- Implemented >> operator for printing
TO DO
Needs a resize function to make it dynamic...Currently it is primarily a container for quick_sort and merge_sort.
CODE
#include "c_include.cpp"
using namespace std;
template <typename> class quick_inner;
template <typename> class merge_inner;
template <class T> class dynamic_array
{
protected:
T* array;
public:
int size;
void rorder();
void order();
void randorder();
void randorder_new();
void print_operator(ostream&)const;
dynamic_array(int sizein)
{
size=sizein;
array=new T[size]();
}
void merge_sort()
{
merge_inner<T> M1(array,size);
}
void quick_sort()
{
quick_inner<T> Q1(array,size);
}
};
template <class T> void dynamic_array<T>::print_operator(ostream &os=cout)const
{
for (int i = 0; i < size; i++) os << array[i] << endl;
}
template <class T> void dynamic_array<T>::randorder()
{
srand(time(NULL));
int *ap,i=0,x;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
++i;
}
for(i=0;i<size;++i)
{
x=(rand()%size);
int tmp=array[x];
array[x]=array[i];
array[i]=tmp;
}
}
template <class T> void dynamic_array<T>::randorder_new()
{
srand(time(NULL));
int *ap,i=0,x;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
++i;
}
for(i=0;i<size;++i)
{
x=(rand()%size);
int tmp=array[x];
array[x]=array[i];
array[i]=tmp;
}
}
template <class T> void dynamic_array<T>::order()
{
int *ap,i=0;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
++i;
}
}
template <class T> void dynamic_array<T>::rorder()
{
int *ap,i=size-1;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
--i;
}
}
template<class T> ostream& operator<<(ostream& stream, dynamic_array<T> const& data)
{
data.print_operator(stream);
return stream;
}
template <class T> class merge_inner
{
public:
merge_inner(T *array_in,int size_in)
{
array=array_in;
size=size_in;
scratch = new T[size]();
if(scratch != NULL){merge_recurse(0, size);}
}
private:
int size;
T *array;
T *scratch;
void flip_if_unordered(int &x, int &y)
{
if(array[x]>array[y])
{
int tmp=array[x];
array[x]=array[y];
array[y]=tmp;
}
}
void merge_algo(int &left, int &right_begin, int &right)
{
int iter,iter_left=left,iter_right=right_begin;
for(iter=left;iter<=right;++iter)
{
if( (iter_right>right) || ((iter_left < right_begin) && (array[iter_left]<=array[iter_right])))
{
scratch[iter]=array[iter_left];
++iter_left;
}
else
{
scratch[iter]=array[iter_right];
++iter_right;
}
}
for(iter=left;iter<=right;++iter){array[iter]=scratch[iter];}
}
void merge_recurse(int left,int right)
{
int left_end=(left+((right-left)/2));
int right_begin=left_end+1;
if(((left+1)==right)){flip_if_unordered(left,right);return;}
else if ((left==right)){return;}
else
{
merge_recurse(left,left_end);
merge_recurse(right_begin,right);
merge_algo(left,right_begin,right);
}
}
};
template <class T> class quick_inner
{
private:
int size;
T* array;
public:
quick_inner(T *array_in,int size_in)
{
array=array_in;
size=size_in;
quick_recurse(0,size);
}
void quick_recurse(int left, int right)
{
int l = left, r = right, tmp;
int pivot = array[(left + right) / 2];
while (l <= r)
{
while (array[l] < pivot)l++;
while (array[r] > pivot)r--;
if (l <= r)
{
tmp = array[l];
array[l] = array[r];
array[r] = tmp;
l++;
r--;
}
}
if (left < r)quick_recurse(left, r);
if (l < right)quick_recurse(l, right);
}
};