- 算法复杂度分为时间复杂度和空间复杂度;
- 时间复杂度:执行算法所需的计算工作量;
- 空间复杂度:执行算法所需的内存空间;
排序方法 | 时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O(n2) | O(n2) | O(n) | O(1) | 稳定 |
快速排序 | O(nlog2n) | O(n2) | O(nlog2n) | O(nlog2n) | 不稳定 |
二分排序 | |||||
快速排序 | |||||
快速排序 | |||||
快速排序 | |||||
快速排序 |
一、冒泡排序
1、基本思想:
每次比较两个元素,若顺序错误就将其交换,重复的进行直到没有元素需要再交换,说明数列排序完成;
2、算法描述:
- 比较相邻元素,若第一个比第二大,交换他们;
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,第一波比较后最后的元素是最大的;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤一到三;
3、比较次数**:
遍历比较次数:最少length-1,最多n(n-1)/2=O(n^2);
元素移动次数:最少0次,最多3n(n-1)/2=O(n^2);
4、代码实现
function bubbleSort(arr){
var i = arr.length-1; //作排序的次数
var temp;
while(i>0){
for(var j=0;j<i;j++){ //一次排序中,比较相邻数据的次数
if(arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
i--;
}
return arr;
}
二:快速排序
1、基本思想
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的数据小,然后再按此方法对这两部分数据对这部分数据分别进行快速排序,整个排序过程可以递归进行,一次达到整个数据编程有序序列;
2、算法描述
- 从数列中挑出一个元素,称为“基准”(pivot);
- 重新排列数列,所有比基准值小的摆放在基准前面,所有比基准小的摆放在后面(相同的数可以到任一边);
- 在这个分区退出之后,该基准就处于数列的中间位置,这个称为分区操作;
- 递归的调用把两部分子数列进行排序;
3、比较次数
4、代码实现
const quickSort = (array) => {
const sort = (arr,left=0,right=arr.length-1)=>{
console.log(left+" "+right)
if(left >= right){ //如果左边的索引大于右边的索引,说明整理完毕
return;
}
let i = left;
let j = right;
const baseVal = arr[j] //取无序数组最后一个数为基准值
while(i<j){
while(i<j && arr[i]<=baseVal ){
i++;
}
arr[j] = arr[i]; //将较大的值放在右边如果没有比基准值大的书就是阿静自己赋值给自己
while( j>i && arr[j] >= baseVal){
j--;
}
arr[i] = arr[j]; //将较小的值防在左边如果没有知道比基准值小的数就是将自己赋值给自己(i=j)
}
arr[j] = baseVal; //将基准值放在中央位置完成一次循环,这时候j=i;
sort(arr,left,j-1); //将左边的无序数组重复上面的操作
sort(arr,j+1,right) //将右边的无序数组重复上面的操作
}
const newArr = array.concat(); //为了保证这个函数是纯函数拷贝一次数组
sort(newArr);
return newArr;
}
console.dir(quickSort([5,6,80,10,65,35]))
三、二分排序法
1、基本思想
2、算法描述
(1):取得数组的中间数为参考数并从数组中删除;
(2):声明两个空数组,左数组,右数组;
(3):遍历数组的每一项,比参考数大的放在左数组,比参考数小的放在右数组
(4):迭代调用函数,并连接左数组,中间数,右数组,返回
3、代码实现
function twoSort(arr){
if (arr.length <= 1) {
return arr;
}
//取得数组中间的数值为参考数
var midNum = arr.splice(Math.floor(arr.length/2),1);
var leftArr = [];
var rightArr = [];
//遍历数组每一项与参考数作对比,小于参考数的放在左侧数组,大与参考数的放在右侧数组
for (var i = 0; i < arr.length; i++) {
if ( parseInt(arr[i]) < midNum ) {
leftArr.push(arr[i]);
} else {
rightArr.push(arr[i])
}
}
//迭代调用函数,并将左数组,参考数,右数组连接起来
return twoSort(leftArr).concat(midNum,twoSort(rightArr));
}
console.log(twoSort([1,50,20]))
四、插入排序
1:基本思想
将一个数据插入到一个已经排好序的序列中并要求插入后此数列依然有序,适用于少量数据的排列
2:算法描述
(1)把要排序的数组分为两部分
(2)一部分包含该数组的全部元素
(3)另一部分只包含插入元素