8.2 简单选择排序
冒泡排序的思想就是不停的交换,通过交换完成最终的排序,但是我们可不可以在排序的过程中找到合适的关键字再做交换,并且只移动一次就完成相应关键字的排序定位工作,这就是选择排序的初步思想。
选择排序的基本思想就是(有n个数据,即长度为n)在 n - start +1 个记录中(start为大循环的开始)选取最小的记录作为有序序列的第start个记录,即经过n - i 次比较,从n - i + 1个记录中选出关键字最小的记录,并和第 start 个记录交换。
复杂度分析:
选择排序最大的特点就睡交换移动数据次数相当少,这样也就节约了相应的时间。分析它的时间复杂度发现,无论最好最差事物情况,其比较的次数都是一样多的,第 i 趟排序需要进行 n - i 次关键词的比较,此时需要比较的次数是 n - 1 + n - 2 + ... + 1 = n * (n - 1)/ 2 次。而对于交换次数而言,当最好的时候,交换为0次,最差的时候,也就是初始降序时,交换次数为 n - 1 次,基于最终的排序时间是比较与交换的次数总和,因此总的时间复杂度依然为 O(n * n)。
应该说,尽管与冒泡排序同为O(n * n),但选择排序的性能还是要优于冒泡排序。
下面是算法的php编程实现:
<?php header("content-type:text/html;charset=utf-8"); /* * 选择法排序: * 两两比较,最小的值在每一次循环的开头 * 时间复杂度:O(N^2);额外空间复杂度O(1) * */ function selectSort1($arr){ if($arr == null || count($arr)<2){ return true; } // echo count($arr); for ($start = 0;$start<count($arr)-1;$start++){//大循环决定开始的位置start,每循环一次开始位置就会向下移一次 $minIndex = $start; //假设最小值索引在开始位置 for($i=$start+1;$i<count($arr);$i++){ $minIndex = ($arr[$minIndex] < $arr[$i]) ? $minIndex : $i; //判断单次循环的最小值,从而确定最小值索引 } swap($arr,$minIndex,$start);//将最小值移到开始的位置 } return $arr; } function swap(&$arr,$i,$j){ //注意这里引用变量的使用 $tem = $arr[$i]; $arr[$i] = $arr[$j]; $arr[$j] = $tem; } $arr = [2,33,45,22,64,67,12,1,0,9]; $arr2 = selectSort2($arr); print_r($arr2);//结果:Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 9 [4] => 12 [5] => 22 [6] => 33 [7] => 45 [8] => 64 [9] => 67 )