1、插入排序:主要思想,将左侧序列看成一个有序序列,每次将一个数字插入该有序序列。插入时,从有序序列最右侧开始比较,若比较的数较大,后移一位,实现代码如下。
var insertSort = function(arr){
for(let i = 0;i<arr.length;i++){
// 将一个值看为最小值
let min =arr[i]
let j
// 将这个最小值循环与左侧的值进行比较,保证左侧数据是有序的
for(j= i - 1; j>=0; j--){
// 如果min大于左侧的值,即符合升序排列,跳出循环
if(arr[j] < min) break
// 否则将arr[j]往后移
arr[j+1] = arr[j]
}
arr[j+1] = min
}
return arr
}
时间复杂度:O(n2)
空间复杂度: O(1)
2、冒泡排序:主要思想,循环数组,比较当前元素和下一个元素,如果当前元素比下一个元素大,向上冒泡。下一次循环继续上面的操作,不循环已经排序好的数,实现代码如下。
var bubbleSort = function(arr){
for(let i = 0;i<arr.length;i++){
for(let j=0;j<arr.length-1-i;j++){
if(arr[j+1] < arr[j]){
[arr[j],arr[j+1]] = [arr[j+1],arr[j]]
}
}
}
return arr
}
时间复杂度:O(n2)
空间复杂度: O(1)
3、选择排序:主要思想,每次排序取一个最大或最小的数字放到前面的有序序列中,实现代码如下。
var choiceSort = function(arr){
for(let i = 0;i<arr.length;i++){
// 第一次循环,假设第一个值为最小值,后面i++依此类推
let min =i
for(let j=i+1;j<arr.length;j++){
// 将第一个值循环与后面的值比较,如果后面的值比第一个值小,则将索引赋值给min,直到找到最小值
if(arr[j] < arr[min]){
min = j
}
}
[arr[i],arr[min]] = [arr[min],arr[i]]
}
return arr
}
时间复杂度:O(n2)
空间复杂度: O(1)
4、快速排序:主要思想,选择一个目标值,比目标值小的放左边,比目标值大的放右边,目标值的位置已排好,将左右两侧再进行快排,实现代码如下。
var quickSort = function(arr){
if(arr.length<=1) return arr
// 找到目标值
let mid = Math.floor(arr.length/2)
// 将值取出来
let temp = arr.splice(mid,1)
// 定义比目标值小的数组,默认为空
let left = []
// 定义比目标值大的数组,默认为空
let right = []
for(let i = 0;i<arr.length;i++){
// 循环将比目标值小的值放入left,大的放入right
if(temp>arr[i]){
left.push(arr[i])
}else{
right.push(arr[i])
}
}
// 返回拼接数组
return quickSort(left).concat(temp,quickSort(right))
}
时间复杂度:平均 O(nlogn),最坏 O(n2),实际上大多数情况下小于 O(nlogn)
空间复杂度: O(logn)(递归调用消耗)
PS:本文中都以升序排列为例!