-
Ordinary binary search
-
Binary search on the left edge
-
Dichotomous cable on the right boundary
-
Binary search implementation details summary
-
Shorthand CARDS
let nums = [1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16]Copy the code
We will use binary search to find the index of element 7 in this array, which is the index of the element shown in the pointer below.
1 Ordinary binary search
let binatySearch = function(nums){
let left = 0, right = nums.length - 1
while (left <= right) {
let mid = (left + right) >> 1
if (nums[mid].value == target) {
return mid
}
else if (nums[mid].value < target) {
left = mid + 1
}
else { // nums[mid].value > target
right = mid - 1}}return - 1
}Copy the code
This public number before an article specifically introduced the cursor animation, how to understand the bubble algorithm of the boundary conditions?
Now the cursor animation has been updated to introduce a new animation element – line segment, let’s call this new animation line segment animation. Line segment animation has part of the characteristics of static visualization.
The interval represented by the left and right Pointers in the figure is [left, right].
From the line segment graph, we can understand the interval variation of left and right Pointers well.
We start with [left, right] representing the elements of the entire array, and then we keep reducing the range in half by the middle value. Because we have an ordered array, we shrink the right pointer if the middle value is greater than the element we’re looking for, and we shrink the left pointer if the middle value is less than the element we’re looking for.
If you understand the range variation, you will understand the code for mid + 1 and mid – 1.
Of course, the most important step in binary search is to take the left and right Pointers of the middle value is also a skill, details can be seen in my article: the clever use of bitwise operation – find the average of two integers
The examples in this article are written in the dumbest possible way to be easy to understand (lazy).
To make the animation easier to understand, elements selected as intermediate values in the diagram are highlighted in other colors.
Note that while (left <= right) why is <=?
While (left < right) = while (left < right)
The disadvantages of ordinary binary search
let nums = [1.2.3.4.4.6.6.6.6.10.11.12.13.14.15.16.16.16.16]Copy the code
2 left boundary binary search
// [left, mid) mid [mid+1, right)
let binatySearchLeftBound = function(nums){
let left = 0, right = nums.length
while (left < right) {
let mid = (left + right) >> 1
if (nums[mid].value == target) {
right = mid
}
else if (nums[mid].value < target) {
left = mid + 1
}
else { // data[mid].value > target
right = mid
}
}
if(nums[left].value ! = target)return - 1
return left
}Copy the code
Left closed right closed interval implementation
// [left, mid-1] mid [mid+1, right]
let binatySearchLeftBoundClosed = function(nums){
let left = 0, right = nums.length - 1
while (left <= right) {
let mid = (left + right) >> 1
if (nums[mid].value == target) {
right = mid - 1
}
else if (nums[mid].value < target) {
left = mid + 1
}
else { // data[mid].value > target
right = mid - 1}}if(nums[left].value ! = target)return - 1
return left
}Copy the code
The animation effect is as follows:
As you can see in this code, while (left <= right) has an equal sign.
Can we sum up a rule one here:
If [left, right), then the condition of the while loop is while (left < right);
If [left, right], then the condition of the while loop is while (left <= right);
Rule 2:
3 right boundary binary search
// [left, mid) mid [mid+1, right)
binatySearchRightBound = function(nums){
let left = 0, right = nums.length
while (left < right) {
let mid = (left + right) >> 1
if (nums[mid].value == target) {
left = mid + 1
}
else if (nums[mid].value < target) {
left = mid + 1
}
else { // data[mid].value > target
right = mid
}
}
if (right <= 0 || nums[right- 1].value ! = target)return - 1
return right- 1
}Copy the code
The animation effect is as follows:
And let’s look at the condition right <= 0. If we are looking for an element that does not exist in the array, such as looking for 0, the animation looks like this.
Without the condition that right <= 0, the right pointer would undoubtedly exceed the bounds of the array as the interval’s right bounds shrink.
Left closed right closed interval implementation
// [left, mid) mid [mid+1, right)
binatySearchRightBoundClosed = function(nums, node, timeline){
let left = 0, right = nums.length - 1
while (left <= right) {
let mid = (left + right) >> 1
if (nums[mid].value == target) {
left = mid + 1
}
else if (nums[mid].value < target) {
left = mid + 1
}
else { // data[mid].value > target
right = mid - 1}}if (right < 0|| nums[right].value ! = target)return - 1
return right
}Copy the code
3 summary
X References
This article refers to a recent popular project labuladong/Fucking algorithm on Github: binary search details.
Review past
Small card
Rule one:
If [left, right), then the condition of the while loop is while (left < right);
If [left, right], then the condition of the while loop is while (left <= right);
Byte armed: Explains all kinds of interesting programming with D3 animations.