首页 > 技术文章 > 8.2 简单选择排序

xlzfdddd 2019-03-05 10:00 原文

冒泡排序的思想就是不停的交换,通过交换完成最终的排序,但是我们可不可以在排序的过程中找到合适的关键字再做交换,并且只移动一次就完成相应关键字的排序定位工作,这就是选择排序的初步思想。

选择排序的基本思想就是(有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 )

 

推荐阅读