各种排序查找的基本算法,持续更新中,分析每个算法时间复杂度。
二分查找
今天去携程面试,出了个二分查找的算法题,算是压死我的最后一根稻草吧,哎,要认认真真地研究基础知识了。
//二分查找-递归方法
function binarySearch(arr, num, lowIndex, highIndex) {
var len = arr.length;
var lowIndex = lowIndex || 0;
var highIndex = highIndex || len - 1
var middleIndex = Math.floor((lowIndex + highIndex) / 2)
if(lowIndex > highIndex) {
return -1
}
if(num === arr[middleIndex]) {
return middleIndex
} else if(num > arr[middleIndex]) {
return binarySearch(arr, num, middleIndex + 1, highIndex)
} else {
return binarySearch(arr, num, lowIndex, middleIndex - 1)
}
return false
}
var numList = [1,2,3,4,5,6,7,8,9]
console.log(binarySearch(numList, 10))
快速排序
快排效率非常高,也是最常用的排序方法,最坏复杂度为O(n^2), 最好时间复杂度为O(nlogn),平均O(nlogn), 空间复杂度为O(logn),不稳定
function quickSort(arr) {
if(arr.length <= 1){return arr}
var pivotIndex = Math.floor(arr.length / 2)
var pivot = arr.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
// arr.
for(var i = 0; i < arr.length; i++) {
if(arr[i] < pivot) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return quickSort(left).concat([pivot], quickSort(right))
}
var numList = [29,1,42,22,14,23,52,312,9,111]
console.log(quickSort(numList))
运行结果: [ 1, 9, 14, 22, 23, 29, 42, 52, 111, 312 ]
二路归并排序
即把两个有序数组合并成一个有序序列,简称二路归并排序
(注:实现方式有局限性,只适用于左数组从头到中间,右数组从中间到尾的数组)
function merge(left, right) {
var result = [];
var leftIndex = 0, rightIndex = 0;
while(leftIndex < left.length && rightIndex < right.length) {
if(left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex])
leftIndex ++;
} else {
result.push(right[rightIndex])
rightIndex ++;
}
}
//左边或者右边有多余的项的时候,直接push剩余项
while(left[leftIndex]) {
result.push(left[leftIndex])
leftIndex ++;
}
while(right[rightIndex]) {
result.push(right[rightIndex]);
rightIndex ++;
}
return result
}
function splitArr(arr) {
var leftArr = [], rightArr = [];
var pivot;
for(var i = 0; i < arr.length; i ++) {
if(arr[i + 1] < arr[i]) {
pivot = i + 1;
leftArr = arr.slice(0, pivot)
rightArr = arr.slice(pivot)
break;
}
}
return {
left: leftArr,
right: rightArr
}
}
var arr = [1,2,3,4,1,3,5,7]
var arrObj = splitArr(arr)
console.log(merge(arrObj.left, arrObj.right))
打印结果: [ 1, 1, 2, 3, 3, 4, 5, 7 ]