排序算法总结

来源:互联网 发布:mac键盘锁住了怎么解锁 编辑:程序博客网 时间:2024/05/14 02:00

        排序算法作为基础的算法,虽然如今没有多少人会自己手动去实现,但作为基础的算法,最近温故了一下,并写了一个简单的测试比较框架,可以给新学习的小伙伴使用同时也自己mark下,以备以后有用。

#include <iostream>#include <algorithm>#include <string>#include <map>#include <time.h>using namespace std;int myRand() {return (rand() % 100);}template <class OType, int count>void prinsourceArray(const OType (&a)[count]){copy(a, a + count, ostream_iterator<OType>(cout, "\t"));}template <int count>void randomArray(int (&arr)[count]) {random_shuffle(arr, arr + count);}template <int count>void copy(int (&source)[count], int (&direction)[count]) {copy(source, source + count, direction);}#define PRINT_SORT(fun, source, param)do {\cout << #fun << " : " << endl;\copy(source, param);\clock_t startTime = clock();\int runTimes = 1000000;\for (int i = 0; i < runTimes; ++i) {\fun(param);\}\clock_t endTime = clock();\prinsourceArray(param);\double runTime = (double)(endTime - startTime) / CLOCKS_PER_SEC / runTimes;\cout << #fun << " run time : " << runTime << "s"<< endl << endl;\resultSet.insert(pair< double, string >(runTime, #fun));\} while(0)// 因为采用数组存储,故需要进行挪位,之前实现的时候,直接交换位置,其实这样也就相当于冒泡排序了//template <int count>//void insertSort(int (&arr)[count]) {//for (int i = 1; i < count; ++i) {//for (int j = i; arr[j] < arr[j - 1] && j > 0;) {//swap(arr[j], arr[j - 1]);//--j;//}//}//}/********************************************插入排序:每次追加元素,都直接将元素插入到其正确的位置,再调整整个序列。********************************************/template <int count>void insertSort(int (&arr)[count]) {for (int i = 1; i < count; ++i) {int j = i;if (arr[i] < arr[i - 1]) {j = i - 1;while (j >= 0 && arr[i] < arr[j]) {--j;}++j;}if (i != j) {int tmpVal = arr[i];copy(arr + j, arr + i, arr + j + 1);arr[j] = tmpVal;}}}//template <int count>//void shellSort(int (&arr)[count]) {//for (int direction = count / 2; direction >= 1; direction /= 2) {//for (int m = 0; m < direction; ++m) {//for (int i = direction + m; i < count; i += direction) {//for (int j = i; arr[j] < arr[j - direction] && j >=direction;) {//swap(arr[j], arr[j - direction]);//j -= direction;//}////}//}//}//}/********************************************希尔排序:多次的插入排序,每次所见插入排序的采样间隔,最后进行一次插入排序。********************************************/template <int count>void shellSort(int (&arr)[count]) {for (int direction = count / 2; direction >= 1; direction /= 2) {for (int m = 0; m < direction; ++m) {for (int i = direction + m; i < count; i += direction) {int j = i;if (arr[i] < arr[i - direction]) {j = i - direction;while(j >= 0 && arr[i] < arr[j]) {j -= direction;}j += direction;}if (i != j) {int tmpVal = arr[i];for (int t = i; t > j; t -= direction) {arr[t] = arr[t - direction];}arr[j] = tmpVal;}}}}}/********************************************选择排序:每次选择一个最大的元素,追加到有序数列末端(最初为空序列,即加入序列即可);升级版本的选择排序:一次寻找最大和最小的元素。********************************************/template <int count>void selectSort(int (&arr)[count]) {for (int i = 0; i < count; ++i) {int minValID = i;for (int j = i; j < count; ++j) {if (arr[minValID] > arr[j]) {minValID = j;}}if (minValID != i) {swap(arr[minValID], arr[i]);}}}template <int count>void updatedSelectSort(int (&arr)[count]) {for (int i = 0; i < count - i; ++i) {int minValID = i;int maxValID = i;for (int j = i; j < count - i; ++j) {if (arr[maxValID] < arr[j]) {maxValID = j;}if (arr[minValID] > arr[j]) {minValID = j;}}if (minValID != i) {swap(arr[minValID], arr[i]);if (maxValID == i) {maxValID = minValID;}}if (maxValID != count - i - 1) {swap(arr[maxValID], arr[count - i - 1]);}}}template <class RandomAccessIterator, class Compare>struct StlFunWraper {typedef void (* SortFun)(RandomAccessIterator first, RandomAccessIterator last, Compare comp);StlFunWraper(SortFun fun) : m_fun(fun) {}template <int count>void operator()(int (&arr)[count]) {m_fun(arr, arr + count, Compare());}SortFun m_fun;};map< double, string > resultSet;template <class k, class T>void printMap(const pair<k, T> &val) {cout << val.first << "\t" << val.second << endl; }const int ACount = 10;int main(){srand(time(0));int sourceArray[ACount];int sortArray[ACount];generate(sourceArray, sourceArray + ACount, myRand);cout << "sourceArray : " << endl;prinsourceArray(sourceArray);cout << endl;                // 框架中,只需要此处添加算法,即可运行并按照运行时间排序        // 这里使用两个数组,主要考虑到每次排序环境一样,才能对算法运行时间进行排序。PRINT_SORT(insertSort, sourceArray, sortArray);PRINT_SORT(shellSort, sourceArray, sortArray);PRINT_SORT(selectSort, sourceArray, sortArray);PRINT_SORT(updatedSelectSort, sourceArray, sortArray);//stl sortPRINT_SORT((StlFunWraper< int[], less<int> >(&sort)), sourceArray, sortArray);cout << "*******************reslut summary******************" << endl;for_each(resultSet.begin(), resultSet.end(), printMap<double, string>);     // 将运行结果增序打出以统计算法的运行事件  return 0;}

        可以看到,其中很多运用到了stl库中的内容,但均起辅助作用,为了框架实现更加方便。

         以下附上运行结果:

sourceArray :
13      61      64      40      90      97      65      33      9       4

insertSort :
4       9       13      33      40      61      64      65      90      97
insertSort run time : 3.1e-008s

shellSort :
4       9       13      33      40      61      64      65      90      97
shellSort run time : 9.3e-008s

selectSort :
4       9       13      33      40      61      64      65      90      97
selectSort run time : 1.25e-007s

updatedSelectSort :
4       9       13      33      40      61      64      65      90      97
updatedSelectSort run time : 1.25e-007s

(StlFunWraper< int[], less<int> >(&sort)) :
4       9       13      33      40      61      64      65      90      97
(StlFunWraper< int[], less<int> >(&sort)) run time : 1.09e-007s

*******************reslut summary******************
3.1e-008        insertSort
9.3e-008        shellSort
1.09e-007       (StlFunWraper< int[], less<int> >(&sort))
1.25e-007       selectSort

        代码中已经附上注释,至于其他几种排序算法,将在后面进一步添加。

 

0 0
原创粉丝点击