码迷,mamicode.com
首页 > 编程语言 > 详细

插入排序

时间:2021-06-13 10:32:18      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:移动   func   cti   php   组元   code   int   存储   使用   

基本思路

插入排序的基本思想可以参考我们整理扑克牌时的情况,当我们刚拿到洗好的牌,我们会按照顺序将每一张牌插入到其他已经有序的牌中。

对应到插入排序,我们可以定义一个操作insertion: 假设我们正在处理第n个元素,首先要比较第n个元素和第n-1个元素,若是arr[n]小于arr[n-1],则交换这两个元素的位置。继续下一轮比较,此时的n已经变成了n-1,我们比较n-1和n-2这两个位置的元素... 依次反复,直到遇到一个比它小的元素,这一趟排序就算结束了。

要保证insertion操作对于第n个元素能够成功排序,唯一的要求是子数组arr[0,1...n-1]是已经有序的,即当n遇到一个比它小的元素min时,确保了min前面的元素都是比小于等于min。

以大小为n的数组arr为例说明:

  • 第一次循环,要进行排序的是第二个元素,很明显子数组为arr[0]只有一个元素,是有序的,设n=1,进行insertion操作,即可把数组arr[0,1]排序。

  • 第二次循环,要进行排序的是第三个元素,此时上一步的操作中,已经把数组arr[0,1]排序了。设n=2,进行insertion操作,即可把数组arr[0,1,2]排序。

  • 第i次循环,要进行排序的是第i个元素,此时上一步的操作中,已经把数组arr[0,1...,i-1]排序了。设n=i,进行insertion操作,即可把数组arr[0,1,...,i-1,i]排序。

PHP代码

function selection_sort(array &$arr)
{
   $n = count($arr);
   for ($i = 1; $i < $n; $i++) {
     for ($j = $i; $j > 0 && less($arr, $j, $j - 1); $j--) {
      	exch($arr, $j - 1, $j);
    }
  }
}

function less(array $arr, int $i, int $j)
{
    return $arr[$i] < $arr[$j];
}


function exch(array &$arr, int $i, int $j)
{
    list($arr[$i], $arr[$j]) = [$arr[$j], $arr[$i]];
}


$arr = [];
for ($i = 0; $i < 10; $i++) {
    $arr[$i] = rand(0, 10000);
}
print_r($arr);
selection_sort($arr);
print_r($arr);

性能

空间复杂度: \(O(1)\)

平均时间复杂度: \(O(n^2)\)

插入排序没有使用额外的存储空间,是原地排序算法,所以空间复杂度为:\(O(1)\)

与选择排序不同,插入排序所需的时间取决于数组元素的初始顺序:

  • 最好的情况:输入的数组已经有序,插入排序只需要n-1次比较和0次交换。

  • 最坏的情况:输入的数组是逆序,每一次遍历都需要比较n-i次并交换n-i次元素,总计:n-1 + n-2 + .... + 2 + 1 = \({N(N-1) \over 2}\)次比较和n-1 + n-2 + .... + 2 + 1 = \({N(N-1) \over 2}\)次交换。

  • 平均的情况: 数组的每个元素都可能向前移动半个子数组的长度,总计:(n-1 + n-2 + .... + 2 + 1)/2 = \({N(N-1) \over 4}\)次比较和(n-1 + n-2 + .... + 2 + 1)/2 = \({N(N-1) \over 4}\)次交换。时间复杂度为: \(O(n^2)\)

插入排序

标签:移动   func   cti   php   组元   code   int   存储   使用   

原文地址:https://www.cnblogs.com/tianjiankun/p/14878755.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!