Searching and Hashing
It is important to understand what search is and when it is appropriate. This page explains sequential and binary search, and their implementation. There is also the matter of hashing as a storage and search technique. In so doing, we introduce the unordered map and how to implement a map abstract data type using hashing. Read Sections 6.1-6.5. You may also find Sections 6.6-6.11 useful for practice.
3. The Sequential Search
3.1. Analysis of Sequential Search
If the item is not in the list, the only way to know it is to compare it against every item present. If there are items, then the sequential search requires comparisons to discover that the item is not there. In the case where the item is in the list, the analysis is not so straightforward. There are actually three different scenarios that can occur. In the best case we will find the item in the first place we look, at the beginning of the list. We will need only one comparison. In the worst case, we will not discover the item until the very last comparison, the nth comparison.
What about the average case? On average, we will find the item about halfway into the list; that is, we will compare against n2 items. Recall, however, that as n gets large, the coefficients, no matter what they are, become insignificant in our approximation, so the complexity of the sequential search, is O (n) . Table 1 summarizes these results.
Table 1: Comparisons Used in a Sequential Search of an Unordered List
We assumed earlier that the items in our collection had been randomly placed so that there is no relative order between the items. What would happen to the sequential search if the items were ordered in some way? Would we be able to gain any efficiency in our search technique?
Assume that the list of items was constructed so that the items were in ascending order, from low to high. If the item we are looking for is present in the list, the chance of it being in any one of the n positions is still the same as before. We will still have the same number of comparisons to find the item. However, if the item is not present there is a slight advantage. Figure 2 shows this process as the algorithm looks for the item 50. Notice that items are still compared in sequence until 54. At this point, however, we know something extra. Not only is 54 not the item we are looking for, but no other elements beyond 54 can work either since the list is sorted. In this case, the algorithm does not have to continue looking through all of the items to report that the item was not found. It can stop immediately. CodeLens 2 shows this variation of the sequential search function.
Figure 2: Sequential Search of an Ordered List of Integers
#include <iostream>
#include <vector>
using namespace std;
// Checks to see if item is in a vector
// retruns true or false (1 or 0)
// using ordered sequential Search
bool orderedSequentialSearch(vector<int> avector, int item) {
unsigned int pos = 0;
bool found = false;
bool stop = false;
while (pos < avector.size() && !found && !stop) {
if (avector[pos] == item) {
found = true;
} else {
if (avector[pos] > item) {
stop = true;
} else {
pos++;
}
}
}
return found;
}
int main() {
// Vector initialized using an array
int arr[] = {0, 1, 2, 8, 13, 17, 19, 32, 42};
vector<int> testvector(arr,arr+(sizeof(arr)/sizeof(arr[0])));
cout << orderedSequentialSearch(testvector, 3) << endl;
cout << orderedSequentialSearch(testvector, 13) << endl;
return 0;
}
C++ Sequential Search of an Ordered vector (search2_cpp)
Table 2 summarizes these results. Note that in the best case we might discover that the item is not in the vector by looking at only one item. On average, we will know after looking through only n/2 items. However, this technique is still . In summary, a sequential search is improved by ordering the vector only in the case where we do not find the item.