几个基础排序算法 #include <iostream> #include <string> using namespace std; extern "C" { extern int rand_n(int, int); } template <typename NumType> class MySort; template <typename NumType> ostream & operator<< (ostream &, const MySort<NumType> &); template <typename NumType> class MySort { private: int count; NumType *data_array; public: friend ostream & operator<< <NumType> (ostream &, const MySort<NumType> &); MySort(NumType *da, int ct) : count(ct) { data_array = new NumType[count]; for (int i = 0; i != count; i++) data_array[i] = da[i]; }; MySort(int n, NumType begin, NumType end); MySort() : data_array(0), count(0) { }; ~MySort() { if (data_array) delete[] data_array;}; void sort(); void insert_sort(); void quick_sort(); void merge_sort(); void merge_sort2(); void heap_sort(); private: inline void swap(NumType &a, NumType &b) { NumType c = a; a = b; b = c; }; void do_quick_sort(int left, int right); void do_merge_sort(int left, int right); // data in half-open [l, r) void do_merge_sort2(NumType *array, int left, int right); // [l, r] void build_heap(); void maintain_heap(int i, int size); int left(int i) { return (i << 1) + 1; }; int right(int i) { return (i << 1) + 2; }; int parent(int i) { return i >> 1; }; }; template<typename NumType> MySort<NumType>::MySort(int n, NumType begin, NumType end) : count(n) { if (n <= 0) { data_array = NULL; count = 0; return; } data_array = new NumType[count]; for (int i = 0; i != n; i++) { data_array[i] = rand_n(begin, end); } } template <typename NumType> void MySort<NumType> ::sort() { int swaped; for (int i = count; i != 0; i--) { int swaped = 0; for (int j = 0; j != i - 1; j++) { if (data_array[j] < data_array[j + 1]) { swap(data_array[j], data_array[j + 1]); swaped = 1; } } if (!swaped) break; } } template <typename NumType> void MySort<NumType>::insert_sort() { for (int i = 1; i != count; i++) { NumType save_val = data_array[i]; int j = i - 1; while (j >= 0 && data_array[j] > save_val){ data_array[j + 1] = data_array[j]; j--; } data_array[j + 1] = save_val; /* for (int j = 0; j != i; j++) { if (data_array[j] > data_array[i]) { NumType save_val = data_array[i]; int shift_end = j; for (j = i; j != shift_end; j--) data_array[j] = data_array[j - 1]; data_array[j] = save_val; } } */ } } template <typename NumType> void MySort<NumType>::quick_sort() { do_quick_sort(0, count); } template <typename NumType> void MySort<NumType>::do_quick_sort(int l, int r) { if (l >= r) return; //int base_idx = rand_n(l, r); //swap(data_array[l], data_array[base_idx]); int base_idx = l; for (int i = l + 1; i != r; i++) { if (data_array[i] < data_array[base_idx]) { swap(data_array[i], data_array[base_idx]); base_idx = i; } } do_quick_sort(l, base_idx); do_quick_sort(base_idx + 1, r); } template <typename NumType> void MySort<NumType>::merge_sort() { do_merge_sort(0, count); } template <typename NumType> void MySort<NumType>::merge_sort2() { NumType *temp_array = new NumType[count]; do_merge_sort2(temp_array, 0, count - 1); delete[] temp_array; } template <typename NumType> void MySort<NumType>::do_merge_sort(int l, int r) { // data in [l, r) if (l == r - 1) return ; if (l < r) { // [ l, (l+r)/2 ), [ (l+r)/2, r ) do_merge_sort(l, (l + r) / 2); do_merge_sort((l + r) / 2, r); } for (int i = l, j = (l + r) / 2; i != j && j != r; i++) { if (data_array[i] > data_array[j]) { NumType save_val = data_array[j]; for (int k = j; k != i; k--) data_array[k] = data_array[k - 1]; data_array[i] = save_val; j++; } } } template <typename NumType> void MySort<NumType>::do_merge_sort2(NumType *temp_array, int l, int r) { // data in [l, r] if (l == r) return ; int m = (l + r) / 2; do_merge_sort2(temp_array, l, m); do_merge_sort2(temp_array, m + 1, r); for (int i = l, j = m + 1, k = 0; k != r - l + 1; k++) { if (i == m + 1 || j == r + 1) { for (; i != m + 1; i++) temp_array[k++] = data_array[i]; for (; j != r + 1; j++) temp_array[k++] = data_array[j]; break; } if (data_array[i] > data_array[j]) temp_array[k] = data_array[j++]; else temp_array[k] = data_array[i++]; } for (int i = 0; i != r - l + 1; i++) data_array[l + i] = temp_array[i]; } template <typename NumType> ostream & operator<< (ostream &os, const MySort<NumType> &s) { os << "sort data:" << endl; for (int i = 0; i != s.count; i++) { os << s.data_array[i] << ", "; if (i % 8 == 7) os << endl; } return os; } /* heap: * left(i) = 2 ( i + 1) - 1 = 2i + 1 * right(i) = left(i) + 1 = 2i + 2 * parent(i) = i / 2 * data[i] >= data[left(i)], data[i] >= data[right(i)] * height = lg (n) * number of leave = (n + 1) / 2 * indice of leave : n / 2, n / 2 + 1, n / 2 + 2, ... , n - 1 */ template <typename NumType> void MySort<NumType>::build_heap() { for (int i = count / 2 - 1; i != -1; i--) { maintain_heap(i, count); #if 0 cout << "the three : <" << i << "," << left(i) << "," << right(i) << "> "; cout << data_array[i] << " " << data_array[left(i)]; cout << " " << data_array[right(i)] << endl; #endif } } template <typename NumType> void MySort<NumType>::maintain_heap(int i, int heap_size) { int max = left(i); if (max >= heap_size) return ; if (right(i) < heap_size && data_array[left(i)] < data_array[right(i)]) max = right(i); if (data_array[i] < data_array[max]) { swap(data_array[i], data_array[max]); maintain_heap(max, heap_size); } } template <typename NumType> void MySort<NumType>::heap_sort() { build_heap(); for (int size = count - 1 ; size != 0; size--) { swap(data_array[size], data_array[0]); maintain_heap(0, size); } } int main(int argc, char **argv) { //MySort<int> hh_test(data_src, sizeof(data_src) / sizeof(int)); int count = 10000, begin = 1, end = 1000000; if (argc < 5) { cout << "usage:" << endl << argv[0] << " count begin end "; cout << "insert|bubble|quick|merge|merge2|heap"; cout << endl; return -1; } count = atoi(argv[1]); begin = atoi(argv[2]); end = atoi(argv[3]); MySort<int> hh_test(count, begin, end); string sort = argv[4]; cout << sort << endl; if (sort == "insert") hh_test.insert_sort(); if (sort == "bubble") hh_test.sort(); if (sort == "quick") hh_test.quick_sort(); if (sort == "merge") hh_test.merge_sort(); if (sort == "merge2") hh_test.merge_sort2(); if (sort == "heap") hh_test.heap_sort(); if (argv[5] && string(argv[5]) == "out") cout << hh_test << endl; }