一,插入排序
1,算法简介
插入排序的工作原理就是将未排序数据,对已排序数据序列从后向前扫描,找到对应的位置并插入。插入排序通常采用占位的形式,空间复杂度为O(1),因此,在从后向前扫描的过程中,需要反复的把已排序的元素逐步向后挪位,为新插入元素提供插入的位置。
2,算法描述
1)从第一个元素开始,该元素可以被认为已经被排序
2)取出下一个元素,在已经排好序的序列中从后往前扫描
3)直到找到小于或者等于该元素的位置
4)将该位置后面的所有已排序的元素从后往前依次移一位
5)将该元素插入到该位置
6)重复步骤2~5
3,算法分析
如果目标是升序排序,那么插入排序有最好情况和最坏情况两种。最好情况是,序列已经是升序排列,那么只需要比较n-1次,当序列是降序排列,那么比较次数是n(n-1)/2,赋值操作是比较次数减去(n-1)次。平均来说,插入算法时间复杂度是O(n^2),空间复杂度是O(1)。我们可以看到,当n较大时,时间复杂度太大,因此插入排序的不适合大数据量的排序,一般来说适合小数据量排序,如n<1000,插入排序也作为快排的补充,当n<8时,使用插排,否则使用快排。
时间复杂度最好为o(n) 最坏为(n^2) 平均为o(n^2) 空间复杂度为o(1) 稳定
4,代码实现function insertSort(arr) { var len =arr.length; for (var i=1;i<len; i++) { var temp=arr[i]; var j=i-1;//默认已排序的元素 while (j>=0 && arr[j]>temp) { //在已排序好的队列中从后向前扫描 arr[j+1]=arr[j]; //已排序的元素大于新元素,将该元素移到一下个位置 j--; } arr[j+1]=temp; } return arr }
5,考察点,重点和考察频度分析
插排由于效率不高,速度较慢,大题考察少,出现频度不高,重点在于时间复杂度、空间复杂度、移动次数考察。
二,二分插入排序
1,算法简介
二分插入排序时一种直接在插入排序上进行小改动的算法,与直接插排最大的区别在于查找插入位置时使用的是二分查找的方式。
2,算法描述
1,从第一个元素开始,认为该元素已排序。
2,取出下一个元素,在已排序序列中二分查找到第一个比它大的数的位置
3,将元素插入到该位置后
4,重复上述两步
3,算法分析
由于只是改进了插入位置查找方法,所以空间复杂度仍然是O(1),插入每个记录需要查找logi次,最多移动i+1次,因此,最佳情况时间复杂度是O(nlogn),最差和平均情况是O(n^2)。
4,代码实现
function binaryInsertSort(arr) {
var len =arr.length;
for (var i=1;i<len; i++) {
var key=arr[i],left=0,right=i-1;
while(left<=right){ //在已排序的元素中二分查找第一个比它大的值
var mid= parseInt((left+right)/2); //二分查找的中间值
if(key<arr[mid]){ //当前值比中间值小 则在左边的子数组中继续寻找
right = mid-1;
}else{
left=mid+1;//当前值比中间值大 在右边的子数组继续寻找
}
}
for(var j=i-1;j>=left;j--){
arr[j+1]=arr[j];
}
arr[left]=key;
}
return arr;
}
5,考察点、重点、频度分析
和直接插排一样,二分插排效率依旧可能不高,这依赖于初始序列,但是二分查找思想是一个很好的思想,重点掌握。