Editing Binary search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 55: | Line 55: | ||
{ | { | ||
int m = (l+r)/2; | int m = (l+r)/2; | ||
− | if (A[m] <= c) /* Note use of < | + | if (A[m] <= c) /* Note use of < instead of <=. */ |
l = m+1; | l = m+1; | ||
else | else | ||
Line 71: | Line 71: | ||
# The index we are seeking is at most <code>r</code>. | # The index we are seeking is at most <code>r</code>. | ||
This is certainly true immediately before the first iteration of the loop, where <code>l = 0</code> and <code>r = n</code>. Now we claim that if it is true before a given iteration of the loop, it will be true after that iteration, which, by induction, implies our claim. First, the value <code>m</code> will be exactly the arithmetic mean of <code>l</code> and <code>r</code>, if their sum is even, or it will be 0.5 less than the mean, if their sum is odd, since <code>m</code> is computed as the arithmetic mean rounded down. This implies that, in any given iteration of the loop, <code>m</code>'s initial value will be at least <code>l</code>, and strictly less than <code>r</code>. Now: | This is certainly true immediately before the first iteration of the loop, where <code>l = 0</code> and <code>r = n</code>. Now we claim that if it is true before a given iteration of the loop, it will be true after that iteration, which, by induction, implies our claim. First, the value <code>m</code> will be exactly the arithmetic mean of <code>l</code> and <code>r</code>, if their sum is even, or it will be 0.5 less than the mean, if their sum is odd, since <code>m</code> is computed as the arithmetic mean rounded down. This implies that, in any given iteration of the loop, <code>m</code>'s initial value will be at least <code>l</code>, and strictly less than <code>r</code>. Now: | ||
− | * ''Case 1'': <code>A[m] < c</code>. This means that no element with index between <code>l</code> and <code>m</code>, inclusive, can be greater than <code>c</code>, because the array is sorted. But because we know that such an element exists (or that it is the hypothetical element just past the end of the array) in the current range delineated by indices <code>l</code> and <code>r</code>, we conclude that it must be in the second half of the range with indices from <code>m+1</code> to <code>r</code>, inclusive. In this case we set <code>l = m+1</code> and at the end of the loop the invariant is again satisfied. This is guaranteed to increase the value of <code>l</code>, since <code>m</code> starts out with value at least <code>l</code>. It also does not increase <code>l</code> beyond <code>r</code>, since <code>m</code> is initially strictly less than <code> | + | * ''Case 1'': <code>A[m] < c</code>. This means that no element with index between <code>l</code> and <code>m</code>, inclusive, can be greater than <code>c</code>, because the array is sorted. But because we know that such an element exists (or that it is the hypothetical element just past the end of the array) in the current range delineated by indices <code>l</code> and <code>r</code>, we conclude that it must be in the second half of the range with indices from <code>m+1</code> to <code>r</code>, inclusive. In this case we set <code>l = m+1</code> and at the end of the loop the invariant is again satisfied. This is guaranteed to increase the value of <code>l</code>, since <code>m</code> starts out with value at least <code>l</code>. It also does not increase <code>l</code> beyond <code>r</code>, since <code>m</code> is initially strictly less than <code>m</code>. |
* ''Case 2'': <code>A[m] >= c</code>. This means that there exists an element with index between <code>l</code> and <code>m</code>, inclusive, which is at least <code>c</code>. This implies that the first such element is somewhere in this half of the range, because the array is sorted. Therefore, after setting <code>r = m</code>, the range of indices between <code>l</code> and <code>r</code>, inclusive, will still contain the index we are seeking, and hence the invariant is again satisfied. This is guaranteed to decrease the value of <code>r</code>, since <code>m</code> starts out strictly less than <code>r</code>; it also will not decrease it beyond <code>l</code>, since <code>m</code> starts out at least as large as <code>l</code>. | * ''Case 2'': <code>A[m] >= c</code>. This means that there exists an element with index between <code>l</code> and <code>m</code>, inclusive, which is at least <code>c</code>. This implies that the first such element is somewhere in this half of the range, because the array is sorted. Therefore, after setting <code>r = m</code>, the range of indices between <code>l</code> and <code>r</code>, inclusive, will still contain the index we are seeking, and hence the invariant is again satisfied. This is guaranteed to decrease the value of <code>r</code>, since <code>m</code> starts out strictly less than <code>r</code>; it also will not decrease it beyond <code>l</code>, since <code>m</code> starts out at least as large as <code>l</code>. | ||
Since each iteration of the loop either increases <code>l</code> or decreases <code>r</code>, the loop will eventually terminate with <code>l = r</code>. Since the invariant still holds, this unique common value must be the solution. <math>_{\blacksquare}</math> | Since each iteration of the loop either increases <code>l</code> or decreases <code>r</code>, the loop will eventually terminate with <code>l = r</code>. Since the invariant still holds, this unique common value must be the solution. <math>_{\blacksquare}</math> |