排序算法03 选择排序及其优化(01)

今天开始写选择排序,选择排序这个效率并不高,写起来也比冒泡算法稍微难搞一点,不过它每次至多交换一次,在某些只需要选择最大或者最小的几个元素的时候是比较实用的。

一、简单的选择排序

上次写冒泡排序的时候,函数参数中使用的是一个函数指针来作为操作排序方式的,这一次该为类型模板了,以便以C++11lambda表达式的时候。auto和迭代器还是没有使用,以便以方便看代码了解排序的思路。

//选择排序的思想和冒泡比较像,也是每次一个沉底(冒泡),与之不同的是每次排序只交换至多一次

//比如有一个序列    3  7  2  5  4  1  6

//从还未排序的序列中选出最大的放在最前面,或者选出最小的放在最后面

//第一次排序后     3  6  2  5  4  1  7     //数字7沉底

//第二次排序后     3  1  2  5  4  6  7     //数字6沉底

//第三次排序后     3  1  2  4  5  6  7

//第四次排序后     3  1  2  4  5  6  7      //此次为发生交换

//第五次排序后     2  1  3  4  5  6  7    

//第六次排序后     1  2  3  4  5  6  7     //此时排序已经完成

//简单的选择排序是 N-1次遍历,每次遍历长度为(N-第几次),交换次数至多一次

 

冒泡排序的过程就如同上面的过程,下面用程序的运行的过程来分析。

如左图中所示,红色框中的是每次选出的最大的值,并把它放置到未排序部分的最后。绿色框中的是未进行交换的遍历。第378次都没有进行过交换。

第一次是原始数据的一次排序后结果,因为没有打印出原始的随机数据,所以不知道是否有交换。

第二次( 41 <-> 39 )

第四次( 33 <-> 5 )

第五次( 26 <->16 )

第六次( 24 <-> 16 )

image

简单的选择排序代码

//使用以下函数调用降序排列,ArrRand2为随机数组,17位元素个数

sort_select(ArrRand2, 17,[](int & a, int &b){return a>b; });

下面贴上实现代码,只给函数了。像是show_arraylessswap这几个函数在冒泡那篇中有。这里就不贴了。

   1: //下面开始来一个简单的选择排序,不做任何优化
   2: //arr 待排序数组,n数组元素个数(为了不使得问题复杂化,暂时不用迭代器)
   3: template<typename T,typename F=bool(*)(const T &,const T &)>
   4: void sort_select(T * arr, unsigned int n, F Less= less)    //默认排序比较
   5: {
   6:     //选择排序的思想和冒泡比较像,也是每次一个沉底(冒泡),与之不同的是每次排序只交换至多一次
   7:     //比如有一个序列   3    7    2    5    4    1    6
   8:     //从还未排序的序列中选出最大的放在最前面,或者选出最小的放在最后面
   9:     //第一次排序后        3    6    2    5    4    1    7        //数字7沉底
  10:     //第二次排序后        3    1    2    5    4    6    7        //数字6沉底
  11:     //第三次排序后        3    1    2    4    5    6    7
  12:     //第四次排序后        2    1    3    4    5    6    7
  13:     //第五次排序后        1    2    3    4    5    6    7        //此时排序已经完成
  14:     //简单的选择排序是 N-1次遍历,每次遍历长度为(N-第几次),交换次数至多一次
  15:  
  16:     unsigned int MaxSite = 0;
  17:     //控制遍历,每次选择最大的放置到末尾
  18:     for (unsigned int i = n - 1; i > 0; --i){
  19:         MaxSite = 0;    //每次先假设第一个就是最大值
  20:         for (unsigned int j = 1; j <= i; ++j){
  21:             if (Less(arr[MaxSite], arr[j])){
  22:                 MaxSite = j;    //寻找最大的位置(下标)
  23:             }
  24:         }
  25:         if (MaxSite != i){    //最大的不是最后一个的时候交换
  26:             swap(arr[MaxSite], arr[i]);
  27:         }
  28:         show_array(arr, n);    //打印一次
  29:     }
  30: }

 

你可能感兴趣的:(排序算法03 选择排序及其优化(01))