#include <iostream>
#include <ctime>
using namespace std;
const int MaxArraySize = 16374;
#ifdef RAND_MAX
#undef RAND_MAX
#define RAND_MAX 1000000
#endif
template <class T>
void bubble_sort(T* array, int s) ...{
bool exchange = true;
int i;
while(exchange) ...{
exchange = false;
for(i = 0; i < s - 1; i++) ...{
if(array[i] > array[i+1]) ...{
T t = array[i];
array[i] = array[i+1];
array[i+1] = t;
exchange = true;
}
}
}
}
template <class T>
void bubble_sort_bound(T* array, int s) ...{
int bound = s - 1, i, t;
while(bound) ...{
t = 0;
for(i = 0; i < bound; i++) ...{
if(array[i] > array[i+1]) ...{
T temp = array[i]; array[i] = array[i+1]; array[i+1] = temp;
t = i;
}
}
bound = t;
}
}
template <class T>
void bubble_sort_bigo(T* array, int s) ...{
int first = 0, last = s-1, i, t;
T temp;
while(first < last) ...{
for(i = first, t = first; i < last; i++) ...{
if(array[i] > array[i+1]) ...{
temp = array[i]; array[i] = array[i+1]; array[i+1] = temp;
t = i;
}
}
last = t;
for(i = last, t = last; i > first; i--) ...{
if(array[i] < array[i-1]) ...{
temp = array[i]; array[i] = array[i-1]; array[i-1] = temp;
t = i;
}
}
first = t;
}
}
template <class T>
void insertion_sort(T* array, int s) ...{
int i,j;
T t;
for(i = 1; i < s; i++) ...{
t = array[i];
j = i - 1;
while(j >= 0 && array[j] > t) ...{
array[j+1] = array[j];
j--;
}
array[j+1] = t;
}
}
template <class T>
void insertion_sort_x(T* array, int s) ...{
int i, j, low, high, mid;
T t;
for(i = 1; i < s; i++) ...{
low = 0; high = i - 1; t = array[i];
while(low <= high) ...{
mid = (low + high) / 2;
if(array[mid] <= t) low = mid + 1;
else if(array[mid] >= t) high = mid - 1;
}
for(j = i - 1; j > high; j--)
array[j+1] = array[j];
array[j+1] = t;
}
}
template <class T>
void select_sort(T* array, int s) ...{
int i,j,k;
for(i = 0; i < s; i++) ...{
k = i;
for(j = i + 1; j < s; j++) ...{
if(array[j] < array[k])
k = j;
}
T t = array[i];
array[i] = array[k];
array[k] = t;
}
}
template <class T>
void merge_sort_x(T* array, int begin, int end) ...{
if(end - begin +1 <= 16) ...{
int i,j;
T t;
for(i = begin + 1; i <= end; i++) ...{
j = i - 1; t = array[i];
while(j >= begin && array[j] > t) ...{
array[j+1] = array[j];
j--;
}
array[j+1] = t;
}
return;
}
if(begin < end) ...{
int mid = (begin + end) / 2;
merge_sort_x(array, begin, mid);
merge_sort_x(array, mid+1, end);
merge_array(array, begin, mid, end);
}
}
template <class T>
void merge_sort_x(T* array, int s) ...{
merge_sort_x(array, 0, s-1);
}
template <class T>
void merge_sort(T* array, int begin, int end) ...{
if(begin < end) ...{
int mid = (begin + end) / 2;
merge_sort(array, begin, mid);
merge_sort(array, mid+1, end);
merge_array(array, begin, mid, end);
}
}
template <class T>
void merge_sort(T* array, int s) ...{
merge_sort(array, 0, s-1);
}
template <class T>
void merge_array(T* array, int begin, int mid, int end) ...{
T *temp = new T[end - begin + 2];
int i = begin,j = mid+1,k = 0;
while(i <= mid && j <= end) ...{
if(array[i] > array[j])
temp[k++] = array[j++];
else
temp[k++] = array[i++];
if(i > mid || j > end)
break;
}
if(i > mid)
while(j <= end) temp[k++] = array[j++];
else
while(i <= mid) temp[k++] = array[i++];
for(i = begin, k = 0; i <= end; i++)
array[i] = temp[k++];
delete[] temp;
}
template <class T>
void build_heap(T* array, int root, int end) ...{
int l = root * 2 + 1, r = root * 2 + 2, b = array[root];
T t;
if(l < end) ...{
if(array[l] > array[root])
b = array[l];
}
if(r < end) ...{
if(array[r] > b)
b = array[r];
}
if(b != array[root]) ...{
t = array[root];
array[root] = b;
if(b == array[l]) ...{
array[l] = t;
build_heap(array, l, end);
} else if(b == array[r]) ...{
array[r] = t;
build_heap(array, r, end);
}
}
}
template <class T>
void heap_sort(T* array, int s) ...{
for(int i = (s - 1)/2; i >= 0; i--)
build_heap(array, i, s);
for(i = s-1; i > 0; i--) ...{
T t = array[0];
array[0] = array[i];
array[i] = t;
build_heap(array, 0, i);
}
}
template <class T>
void quick_sort(T* array, int begin, int end) ...{
T key = array[begin];
int i = begin, j = end;
if(begin < end) ...{
while(i < j) ...{
while(++i < end && array[i] < key);
while(--j > begin && array[j] > key);
if(i < j) ...{
T t = array[i]; array[i] = array[j]; array[j] = t;
}
}
array[begin] = array[j];
array[j] = key;
quick_sort(array, begin, j);
quick_sort(array, j+1, end);
}
}
template <class T>
void quick_sort(T* array, int s) ...{
quick_sort(array, 0, s);
}
template <class T>
void quick_sort_x(T* array, int begin, int end) ...{
int i,j;
T t;
if(end - begin <= 16) ...{
for(i = begin + 1; i < end; i++) ...{
j = i - 1; t = array[i];
while(j >= begin && array[j] > t) ...{
array[j+1] = array[j]; j--;
}
array[j+1] = t;
}
return;
}
if(begin < end) ...{
t = array[begin];
i = begin;
j = end;
while(i < j) ...{
while(++i < end && array[i] < t);
while(--j > begin && array[j] > t);
if(i < j) ...{
T temp = array[i]; array[i] = array[j]; array[j] = temp;
}
}
array[begin] = array[j];
array[j] = t;
quick_sort_x(array, begin, j);
quick_sort_x(array, j+1, end);
}
}
template <class T>
void quick_sort_x(T* array, int s) ...{
quick_sort_x(array, 0, s);
}
template <class T>
void print(T* array, int s) ...{
for(int i = 0; i < s; i++)
cout << array[i] << ' ';
cout << endl;
}
void generate_test(int *array, int s) ...{
srand(time(NULL));
for(int i = 0; i < s; i++)
array[i] = rand();
}
void sleep(clock_t wait) ...{
clock_t dest = clock() + wait;
while(dest > clock());
}
template <class T>
struct SortF ...{
void (*test_f)(T* array, int);
char *description;
};
int testArray[MaxArraySize], testCopy[MaxArraySize], i;
int main() ...{
clock_t start, finish;
SortF<int> function_array[] = ...{
bubble_sort, "普通的冒泡排序,到没有交换时停止",
bubble_sort_bound, "改进的冒泡排序,记录最后一次交换位置",
bubble_sort_bigo, "改进的冒泡排序,双向进行冒泡",
insertion_sort, "普通插入排序",
insertion_sort_x, "改进的插入排序,使用二分检索查找插入位置",
select_sort, "选择排序",
heap_sort, "堆排序",
quick_sort, "普通快速排序",
quick_sort_x, "改进的快速排序,小范围内使用插入排序改进",
merge_sort, "普通合并排序",
merge_sort_x, "改进后的合并排序,小范围内使用插入排序改进"
};
generate_test(testCopy, MaxArraySize);
for(i = 0; i < sizeof(function_array)/sizeof(SortF<int>); i++) ...{
cout << "test " << function_array[i].description << endl;
memcpy(testArray, testCopy, sizeof(testArray));
cout << "before sort: ";
if(MaxArraySize <= 40)
print(testArray, MaxArraySize);
start = clock();
function_array[i].test_f(testArray, MaxArraySize);
finish = clock();
cout << "after sort: ";
if(MaxArraySize <= 40)
print(testArray, MaxArraySize);
cout << "consume time: " << (double)(finish - start) / CLOCKS_PER_SEC << endl << endl << endl;
//sleep(1000);
}
return 0;
}