From: http://blog.csdn.net/hackbuteer1/article/details/7581596
Binary Search and its extension (search in an incremental array) classification: Interview Pearl 2012-05-18 1076 people read comments (6) collections report binary search needs to pay attention to the closed interval issue, the constraints and boundaries must be paired: low <= high, low = Mid + 1, high = mid-1.
The binary search template is as follows:
[CPP]View plaincopy
- // Binary Search
- Int binarysearch (int * num, int key, int low, int high)
- {
- Int mid;
- While (low <= high) // remember: the condition is <=, many times are accidentally written as <, resulting in N + wa
- {
- Mid = (low + high)> 1;
- If (Num [Mid] = key)
- Return mid;
- Else if (Num [Mid] <key)
- Low = Mid + 1;
- Else
- High = mid-1;
- }
- Return low; // if the search is unsuccessful, return the location where the insertion is expected, or directly return-1, indicating that the search fails.
- }
Extension of Binary Search: binary search can be quickly used for sorted array. There is a special array a [], which increments cyclically, for example, a [] = {17 19 20 25 1 4 7 9 }, try to find an element x in this array to see if it exists. Write your algorithm, write pseudocode if necessary, and analyze its space and time complexity.
For an array in a circular order, it increments cyclically. For example: A [] = {17 19 20 25 1 4 7 9}, you can also use a binary search: each time an array is divided into two parts, one is monotonically increasing, and the other is cyclically increasing. If it is monotonically incrementing, you can directly use the simple binary search. If it is cyclically incrementing, you can continue to use the Special binary search.
Train of Thought Analysis:
Retrieve an element from an array. The most common algorithm is sequential search with the time complexity of O (n. To reduce the time complexity and combine the elements in an array with an increasing number of loops with a certain degree of order, it is easy to think of binary search.
My original idea was: the simple binary search performs binary search in the subscripts range [0 n-1], so we can use the cyclical incremental nature, we can perform binary division in an offset range [R + 1 N + r-1] of the effective subscript range [0 n-1] of the array (where R is the demarcation subscript defined in the above-mentioned loop incrementing array) r ). However, one of the biggest problems with this idea is: How can I determine the subscripts R for a given array with an increment loop? The most obvious method is to scan the array sequentially and determine its subscripts R. However, since you have scanned all of them, you can determine whether the retrieval element is in the array. Why use the submark R to search?
If the above ideas fail, let's go into depth and think about some of the principles and features of the binary search method. In a strictly incrementing array, we compare the elements to be retrieved with the elements in the middle of the array, then, based on the relationship between the element to be retrieved and the element in the middle of the array, the element falls within that range, and then recursively searches within this range.
In an array with an ascending loop, we cannot simply determine the range of elements to be retrieved by the relationship with the size of elements in the array. To determine the range, we can add the relationship between the elements to be retrieved and the elements at both ends of the array.
An array with an ascending loop has the following properties: An array with an ascending loop is divided into two parts by the elements in the array. Then, one part is a strictly incrementing array, and the other part is a smaller one. When the middle element is greater than the first element, the first half is divided into a strictly incrementing array, and the second half is a circular incrementing array; when the middle element is smaller than the first element, the first half is divided into a circular incrementing array; the second half is a strictly incrementing array.
The element to be retrieved is the key, the first element of the array is a [low], the middle element is a [Mid], and the end element is a [High]. When the key is not equal to a [Mid,
1. A [Mid]> A [low], that is, when the first half of the array is strictly incrementing, if the key is smaller than a [Mid] and not less than a [low], the key falls into the first half of the array; otherwise, the key falls into the second half of the array.
2. A [Mid] <A [High], that is, when the first half of the array is an array with an ascending loop, if the key is greater than a [Mid] and not greater than a [High], the key falls into the second half of the array; otherwise, the key falls into the first half of the array.
Using the first element of the array, the middle element and the end element to determine the range of the element to be retrieved, we can use the modified binary search algorithm.
The implementation code is as follows:[CPP]View plaincopy
- // Improved Binary Search
- Int search (int A [], int N, int num)
- {
- Int left = 0;
- Int right = n-1;
- Int mid = 0;
- Int Pos =-1; // returns-1, indicating that the search failed.
- While (left <= right)
- {
- Mid = (left + right)/2;
- If (A [Mid] = num)
- {
- Pos = mid;
- Break;
- }
- If (A [left] <= A [Mid]) // The first half is strictly incrementing, and the second half is a smaller cyclic incrementing array.
- {
- If (A [left] <= num & num <A [Mid])
- {
- Right = mid-1;
- }
- Else
- {
- Left = Mid + 1;
- }
- }
- Else // The second half is strictly incrementing, and the first half is a smaller cyclic incrementing array.
- {
- If (A [Mid] <num & num <= A [right])
- {
- Left = Mid + 1;
- }
- Else
- {
- Right = mid-1;
- }
- }
- }
- Return Pos;
- }