本文参考链接:www.cnblogs.com/onepixel/p/…
前言
平时很少系统的写过排序算法,只有在用的时候才会去写,这次准备认真的分析一下各种优秀排序算法,发现自己以前对很熟悉的冒泡的理解都存在误区,这次学习受益良多,有时间的话推荐系统的分析一下各类排序算法,要用的时候根据不同情况直接就可以使用了。
1,冒泡排序
算法描述
- 比较两个相邻的元素,如果第一个比第二个大,则交换它们的位置;
- 注意第二层循环的结束的位置可以-i,因为后i位都是排好序的(我以前是没有-i的,会做无用功)
代码实现
function bubbleSort(arr)
{
for(let i = 0;i<arr.length;i++)
for(let j = 1;j+1<arr.length-i;j++)
{
if(arr[j]>arr[j+1])//决定是否稳定的条件,如果>=则是不稳定的
{
let temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
return arr;
}
复杂度分析
- 时间复杂度:两层循环,所以O(n^2);
- 空间复杂度:使用常量temp所以O(1);
- 稳定性:稳定
2,选择排序
算法描述
- 首先在未排序序列中找到最大(小)的元素,将其存放在有序列表的首部,然后继续在未排序序列中找极值,然后存在有序列表的尾部。
代码实现
function selectSort(arr)
{
let minindex,temp;
for(let i = 0;i<arr.length-1;i++)
{
minindex = i;
for(let j = i+1;j<arr.length;j++)
{
if(arr[j]<arr[minindex])//寻找最小的数
minindex = j;//修改最小值的下标
}
temp = arr[i];
arr[i] = arr[minindex];
arr[minindex] = temp;
}
return arr;
}
复杂度分析
- 时间复杂度:同样两层嵌套循环,所以O(n^2);
- 空间复杂度:使用常量temp所以O(1);
- 稳定性:不稳定(比如 5 2 5 1)
3,插入排序
算法描述
- 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入;
代码实现
function insertSort(arr)
{
let preIndex,current;
for(let i = 1;i<arr.length;i++)
{
preIndex = i-1;
current = arr[i];
while(preIndex>=0 && arr[preIndex]>current)//在有序序列中找比当前元素大的下标
{
arr[preIndex+1] = arr[preIndex];//找到之后将此元素往后移一个单位,
preIndex--;
}
arr[preIndex+1] = current;//将当前元素插入指定位置
}
return arr;
}
复杂度分析
- 时间复杂度:平均O(n^2);
- 空间复杂度:常量级O(1);
- 稳定性:稳定
4,快速排序
算法描述
- 从数列中挑出一个元素,称为 “基准”(flag);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面,在这个分区退出之后,该基准就处于数列的中间位置。
- 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序
代码实现
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function quickSort(arr,left,right)
{
let partitionIndex;
if(left<right)
{
partitionIndex = partition(arr,left,right);
quickSort(arr,left,partitionIndex-1);
quickSort(arr,partitionIndex+1,right);
}
return arr;
}
function partition(arr,left,right)//分区操作
{
let flag = left;//基准
let index = flag+1;
for(let i = index;i<=right;i++)
{
if(arr[i]<arr[flag])
{
swap(arr,index,i);
index++;
}
}
swap(arr,flag,index-1);
return index-1;
}
复杂度分析
- 时间复杂度:由于存在二分思想,所以复杂度比较低平均O(nlgn);
- 空间复杂度:由于有递归调用占用内存,所以O(lgn);
- 稳定性:不稳定(5 | 3 1 2 | 9 7 8 9 | 4 6 3)4会和前面的9换位置;