一、选择法排序、冒泡排序、插入法排序
二、快速排序、分治法排序、堆排序
三、计数排序、基数排序、桶排序
gtest介绍及测试用例如下:测试框架之GTest
MIT《算法导论》下载:hereorhttp://download.csdn.net/detail/ceofit/4212385
源码下载:here orhttp://download.csdn.net/detail/ceofit/4218488
中位数
中位数用于查找序列中指定大小位置的数值。包括求最大值、最小值、中间指定第pos小的值。
最大值、最小值比较简单,在排序算法 零中已有介绍。
不多说了,代码很简单,大家一看就懂,时间复杂度n,空间复杂度1
int get_max(int *pArray,int cnt) { if(cnt <= 0) return 0; int max = pArray[0]; int i = 0; for(i=1; i<cnt; i++) { max = max>=pArray[i] ? max : pArray[i]; } return max; } int get_min(int *pArray,int cnt) { if(cnt < 0) return 0; int min = pArray[0]; int i = 0; for(i=1; i<cnt; i++) { min = min<=pArray[i] ? min : pArray[i]; } return min; }
求指定位置pos的数值也有很多方法,最直接的就是排序,排序后直接取下标,但时间复杂度、空间复杂度与排序算法一致,且原序列发生了变化。
也可借助快速排序的思想,可得到最优情况下时间复杂度平均为n,空间复杂度为1的算法。而最坏情况下时间复杂度为n*n。
由于快排最坏情况下时间复杂度为n*n,因此前面提出了随机化快速排序的方法,可使时间复杂度接近nlgn。
而此处的中位数查找,使用随机化的思想,可使时间复杂度接近n。
前面讲过,快排的原理是比如将第1个数值,一层排序可直接找到其位置,然后对齐高位、低位分别递归。利用这个一步到位的思想,在递归的过程中,如果得到位置为pos的数值直接返回即可。为优化速度,递归过程中不需要按照快排高低位都递归,只需递归一边即可。
#include "SK_Common.h" #include "SK_Sort.h" //将第1个元素移动到指定位置,且保证小于此元素的在其左边,大于的在其右边 static int get_middle(int *pArray,int start,int end) { if(start >= end) return start; int midvalue = pArray[start]; int save_ptr = start; int front_ptr = start; while(front_ptr <= end) { if(pArray[front_ptr] < midvalue) { pArray[save_ptr] = pArray[front_ptr]; pArray[front_ptr] = pArray[save_ptr+1]; save_ptr++; } front_ptr++; } pArray[save_ptr] = midvalue; return save_ptr; } //随机化方法,查找随机位置,与第1位交换。 int get_middle_random(int *pArray,int start,int end) { int mid = get_random(start,end); exchange(pArray+start,pArray+mid); return get_middle(pArray,start,end); } int _quick_search(int *pArray,int start,int end,int pos) { if(start >= end) return pArray[end]; int mid = get_middle_random(pArray,start,end); if(mid == pos) //找到 return pArray[mid]; else if(pos < mid) //pos在低位 return _quick_search(pArray,start,mid-1,pos); else //pos在高位 return _quick_search(pArray,mid+1,end,pos); } int QuickSearch(int *pArray,int cnt,int pos) { if(cnt <= 0) { return 0; } if(pos > cnt) pos = cnt; return _quick_search(pArray,0,cnt-1,pos-1); }
随机情况下时间复杂度平均为n,空间复杂度为1,但原始序列发生了改变。
如果要求原始序列不变,可复制一份,以备份查找,空间复杂度n。
时间复杂度平均为n的计算方法在书中介绍的很详细,且公式比较多,大家有兴趣的花翻书看看。