1. 二分查找
二分查找是一个基础的算法,二分查找就是将查找的键和子数组的中间键做比较,如果被查找的键小于中间键,就在左子数组中继续查找,如果大于中间键就在右子数中查找,否则中间键就是要找的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function binarySearch(arr, key) { let left=0; let right=arr.length-1; while(left <= right){ let mid = Math.floor((left+right)/2); if(arr[mid] === key) { return mid; }else if(arr[mid]<key){ left = mid+1; }else{ right = mid-1; } } return -1; }
|
2. 二分查找的变种
2.1 查找第一个与key相等的元素
也就是查找下标最小的与key相等的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function findFirstEqual(arr, key) { let left=0; let right=arr.length-1; while(left <= right){ let mid = Math.floor((left+right)/2); if(arr[mid] >= key) { right = mid - 1; }else{ left = mid + 1; } } if(left<arr.length && arr[left] === key) { return left; } return -1; }
|
2.2 查找最后一个与key相等的元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function findLastEqual(arr, key) { let left=0; let right=arr.length-1; while(left <= right){ let mid = Math.floor((left+right)/2); if(arr[mid] <= key) { left = mid + 1; }else{ right = mid - 1; } } if(right<arr.length && arr[right] === key) { return right; } return -1; }
|
2.3 查找第一个等于或者大于key的元素(对照2.1)
1 2 3 4 5 6 7 8 9 10 11 12 13
| function findFirstEqualOrLarger(arr, key) { let left=0; let right=arr.length-1; while(left <= right){ let mid = Math.floor((left+right)/2); if(arr[mid] >= key) { right = mid - 1; }else{ left = mid + 1; } } return left; }
|
2.4 查找最后一个等于或者小于key的元素(对照2.2)
1 2 3 4 5 6 7 8 9 10 11 12 13
| function findLastEqualOrSmaller(arr, key) { let left=0; let right=arr.length-1; while(left <= right){ let mid = Math.floor((left+right)/2); if(arr[mid] <= key) { left = mid + 1; }else{ right = mid - 1; } } return right; }
|
2.5 查找第一个大于key的元素(对照2.3)
1 2 3 4 5 6 7 8 9 10 11 12 13
| function findFirstLarger(arr, key) { let left=0; let right=arr.length-1; while(left <= right){ let mid = Math.floor((left+right)/2); if(arr[mid] > key) { right = mid - 1; }else{ left = mid + 1; } } return left; }
|
2.6 查找最后一个小于key的元素(对照2.4)
1 2 3 4 5 6 7 8 9 10 11 12 13
| function findLastSmaller(arr, key) { let left=0; let right=arr.length-1; while(left <= right){ let mid = Math.floor((left+right)/2); if(arr[mid] < key) { left = mid + 1; }else{ right = mid - 1; } } return right; }
|