js中常见的排序算法
1. 冒泡排序
开始交换的区间为0~N-1,将第1个数和第2个数进行比较,前面大于后面,交换两个数,否则不交换。再比较第2个数和第三个数,前面大于后面,交换两个数否则不交换,依次进行。
a.时间复杂度:平均时间复杂度是O(n^2),在最佳状态时,时间复杂度也会缩小到O(n);
b.空间复杂度:由于辅助空间为常数,所以空间复杂度是O(1);
var arr=[1,2,333,100,34,6,78,0]; // 9 10 8 // 1.为什么外层循环长度需要减1?减少不必要的循环(8,14,7,三个数其实只要比较两次) // 2.为什么不直接使用第二层循环进行排序呢?只是两两比较如,(8,14,7),结果(8,7,14),并没有预期的排序效果。 function bubbleSort(arr){ for(var i=0;i<arr.length-1;i++){ for(var k=0;k<arr.length-1-i;k++){ if(arr[k]>arr[k+1]){ var temp=arr[k]; arr[k]=arr[k+1]; arr[k+1]=temp; } } } return arr; }
这种排序有个问题,如果数组是 [9,8,7,6,5,4,3,2],则排一次后就已经是我们需要的结果了。
如果某一趟排序后,我们发现没有交换位置,则说明待排序中所有的项已经是排序过的了,则没必要进行下去。
function bubbleSort(arr){ for(var i=0;i<arr.length-1;i++){ // 每一趟循环前都需要重置标志位 let shouldSort=false; for(var k=0;k<arr.length-1-i;k++){ if(arr[k]>arr[k+1]){ var temp=arr[k]; arr[k]=arr[k+1]; arr[k+1]=temp; shouldSort=true; } } // 在本轮循环后,如果没有发生位置变化,则停止执行了 if(!shouldSort){ console.log("已经完成目标了,休息一下吧"); break; } } return arr; }
快速排序(递归)
时间复杂度
a.最优情况下的时间复杂度为O(nlogn)
b.最差情况下,每次选取的基数都是数组中的最大或最小值,整个排序过程退化为插入排序,递归迭代时间复杂度为O(n),左右指针向基数移动的时间复杂度为O(n),故快排最差情况下的时间复杂度为O(n^2)
平均复杂度: 快速排序的平均时间复杂度也是:O(nlogn)
空间复杂度:
a.最优的情况下空间复杂度为:O(logn)
b.最差的情况下空间复杂度为:O( n )
const arr = [30, 32, 6, 24, 37, 32, 45, 21, 38, 23, 47]; function quickSort(arr){ if(arr.length <= 1){ return arr; } let temp = arr[0]; const left = []; const right = []; for(var i = 1; i < arr.length; i++){ if(arr[i] > temp){ right.push(arr[i]); }else{ left.push(arr[i]); } } return quickSort(left).concat([temp], quickSort(right)); } console.log(quickSort(arr));