排序算法总结

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

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值