冒泡排序
冒泡排序算法描述:使用冒泡排序把一个无序的数组按照从小到大的顺序排列的,思路是:首先需要双重遍历这个数组,首先拿出来第一个和后面的第二个做对比,如果前面的比后面的值大,这两个值就做交换,否则就不执行任何操作,然后再对比第二个和第三个。。。依次类推,直到比较到最后一个。这样外层循环每循环一次都会冒出一个当前最大的值,这个值确定之后,我们就不用再管这个位置的值了,然后再对比前面的即可。
算法如下所示:
function bubbleSort(arr){
for(let i=0; i<arr.length-1; i++){
for(let j=0; j<arr.length-i-1; j++){
if(arr[j] > arr[j+1]){
[arr[j], arr[j+1]] = [arr[j+1], arr[j]]
}
}
}
}
let arr = [3,2,1]
bubbleSort(arr)
console.log(arr)
从算法中我们可以看出:
外层循环下标的范围是[0, arr.length-1), 只需要比较arr.length-1次
内层循环下标的范围是[0, arr.length-i-1), 因为外层循环多少次就确定了这个数组后面几位的排列顺序,所以下一次的循环就不用管之前已经排好的位置了。
插入排序
插入排序算法描述:插入排序首先需要声明一个新的数组newArr,把要排序的数组arr的第一个放在这个数组中,然后从要排序的数组的第二个开始依次取值,准备逐个插入到新的数组newArr中,插入之前需要判断插入的位置。当我们拿出要排序的数组的第二个数时,就要从后向前遍历新的数组newArr,判断newArr的最后一个是不是比刚拿出来的数大,如果不是,就直接插入到新数组newArr的最后一个后面的位置,如果是,需要判断新数组newArr当前的下表 j 是不是0 ,如果是0 ,就直接插入到最前面,如果不是0,就继续和前一个做对比,如果比前一个大,就直接插入到这个数之前,如果不是继续向前循环做对比。
算法如下:
function insertSort(arr){
let newArr = []
newArr.push(arr[0])
for(let i=1; i<arr.length; i++){
for(let j=newArr.length-1;j>=0;j--){
if(arr[i]<newArr[j]){
if(j==0){
newArr.unshift(arr[i])
break
}
if(arr[i]>newArr[j-1]){
newArr.splice(j,0,arr[i])
break
}
}else{
arr.push(arr[i])
break
}
}
}
return newArr
}
let arr = [3,2,1]
insertSort(arr)
从算法中可以看出:
外层循环的范围是[1, arr.length),因为要把每一个都拿出来放到一个新数组中,但是第一个已经默认放到了新数组中,就不需要循环做对比了
内层循环的范围是[0, newArr.length-1],而且每次都是从新数组的最后一个做对比,比最后一个大就直接插入到最后一个,比前一个小就再循环向前找,直到找到比第一个还小就直接插入到最前面,或者直到找到比当前值小,但是比前一个大才插入到当前位置的前面。
**注意:**只要拿出的原来数组的值插入到新的数组中,就在后面 break 结束循环
快速排序
快速排序算法描述:首先声明两个数组left和right,拿出数组的第一个,从第二个开始循环遍历,如果比第一个大就放在right数组中,如果比第一个小就放在left数组中,然后递归right数组和left数组,递归终止的条件就是当前数组的长度是1或者0,每次调用快速排序函数都需要将两个数组和原数组的第一个值做合并
function quickSort(arr){
if(arr.length == 1 || arr.length == 0){ // 递归中终止的条件
return arr
}
let temp = arr[0]
let left = []
let right = []
for(let i=1; i<arr.length; i++){
if(arr[i]<temp){
left.push(arr[i])
}else{
right.push(arr[i])
}
}
return quickSort(left).concat(temp, quickSort(right))
}
let arr = [3,2,1]
console.log(quickSort(arr))
从算法可以看出:
快速排序需要使用到递归的思想,每次都将一个数组分割为一个单独的值和两个数组,递归结束后需要再合并为一个数组。