冒泡排序
通过相邻元素的比较和交换,使得每一趟循环都能找到未有序数组的最大值或最小值。
// 最好:O(n),只需要冒泡一次数组就有序了。
// 最坏:O(n²)
// 平均:O(n²)
function bubbleSort(arr){
for(let i = 0,len = arr.length; i<len; i++){
for(let j = 0; j<len-i-1; j++){
if(arr[j]>arr[j+1]){
[arr[j],arr[j+1]] = [arr[j+1],arr[j]
}
}
}
return arr
}
选择排序
和冒泡排序相似,区别在于选择排序是将每一个元素和它后面的所有元素进行比较和交换。
// 最好:O(n²)
// 最坏:O(n²)
// 平均:O(n²)
function chooseSort(arr){
for(let i = 0,len = arr.length; i<len; i++){
for(let j = i+1; j<len;j++){
if(arr[i]>arr[j]){
[arr[i],arr[j]] = [arr[j],arr[i]]
}
}
}
return arr
}
快速排序
选择一个元素作为基数(通常是第一个元素),把比基数小的元素放到它左边,比基数大的元素放到它右边(相当于二分),再不断递归基数左右两边的序列。
// 最好:O(n * logn),所有数均匀分布在基数的两边,此时的递归就是不断地二分左右序列。
// 最坏:O(n²) ,所有数都分布在基数的一边,此时划分左右序列就相当于是插入排序。
// 平均:O(n * logn)
// 默认取第一个数作为基数,所以先从右边向中间推。遇到小于基数的数就赋给左边的坑位(一开始是基数的位置),而这个小于基数的数则由基数填上,这样基数右边的数就都大于基数了。右边保留原先的值等之后被左边的值填上。
function quickSort(arr){
function des(arr,left,right){
let temp = arr[left]
while(left<right){
while(left<right && arr[right]>=temp){
right--
}
arr[left] = arr[right]
while(left<right && arr[left]<=temp){
left++
}
arr[right] =arr[left]
}
arr[left] = temp
return left
}
function rev(arr,left,right){
if(left>=right) return
let index = des(arr,left,right)
rev(arr,left,index-1)
rev(arr,index+1,right)
}
return rev(arr,0,arr.length-1)
}