TODAY WE START DOING REAL COMPUTER SCIENCE!!!!!
We will look at algorithms to solve general problems, we will study how
to implement them, and then show how to analyze the algorithms that we
create.
Searching
Input: Array A[0..n-1] of n elements, and a value x.
Output: An index i such that A[i] == x, or -1 if A[i] != x for
all 0 <= i < n.
See Demo linearSearch0.cpp
- This algorithm checks all n positions.
- We do n comparisons agains x no matter where x is.
- We must perform n + 1 loop bound checks.
- Therefore, there are n + n + 1 = 2n + 1 comparisons in total.
Can improve on previous implementation. See Demo linearSearch1.cpp
- The previous algorithm searched through all items in the array A,
whether or not it found x.
- This algorithm stops searching when we find x.
- If x is not found:
- We must perform n comparisons against x.
- And another n + 1 loop bound checks.
- This gives n + n + 1 = 2n + 1 comparisons.
- If x is found in A[i]:
- We need i + 1 comparisons against x.
- We need another i + 1 loop bound checks.
- Plus one check at the end.
- this gives (i + 1) + (i + 1) + 1 = 2i + 3 comparisons.
- The order of the loop test is important
- i < n && (and then) A[i] != x.
- The short-circuiting && operator prevents us from looking at A[i]
when i >= n. That's the right thing to do, since A[i] is undefined
for i >= n.
Can improve on previous implementation still. See Demo
linearsearch2.cpp
- It would be nice to eliminate the loop bound check.
- So to do this, we ensure that x will be found.
- We set A[n] = x so that we do not fall off the end of the array.
- When we do this, the x in position A[n] is called a
sentinel.
- Beware, for inserting the sentinel in this case requres that we
have space for an extra element allocated in A.
- What we obtain is much cleaner code.
- In the case that x is not found:
- We need n + 1 comparisons against x.
- We need 0 loop bound checks since we eliminated them completely.
- Plus checks at the beginning and the end of the algorithm.
- If x is found in A[i]:
- We need i + 1 comparisons against x.
- We again need 0 loop bound checks.
- Plus checks at the beginning and the end of the algorithm.
- As you can see we eliminated half of the checks by removing the loop
check bounds and so this implementation will be twice as fast.
This is about the best we can do if we have no further information
about the array. But what if...
The array A is sorted
Array A is sorted if
A[0] <= A[1] <= A[2] <= ... <= A[N-2] <= A[N-1] .
For example, the following array is sorted:
Suppose we search for the element 12, which is not in the above
array. We can stop when we get to A[3] == 13 because 12 < 13 and all
the entries after A[3] are >= 13. So how do we implement this
improvement?
Let's try Demo linearSearch3.cpp
- The loop test that is done is
i < n && A[i] < x
- If x is found in A[i]:
- i + 1 comparisons are done against x in the loop.
- Plus 1 comparison at the end.
- We need i + 1 comparisons of the form i < n done in the loop.
- Plus 1 more comparison at the end.
- This gives: (i + 1) + 1 + (i + 1) + 1 = 2i + 4.
- If x is not found:
- We have 2i + 4 comparisons if A[i - 1] < x < A[i].
- And 4 comparisons if x < A[0].
- This is better than the linearSearch1 implementation.
- However, if x > A[n - 1] then there will be 2n + 2 comparisons. (2n + 1
in the loop plus 1 at the end.)
- This is about the same as linearSearch1.
So is it possible to combine both ideas and use a sentinel with a
sorted array? You bet! Graphically, we would alter our previous
sorted array to be:
And the code is in linearSearch4.cpp
- We use the x that we are seaching for as the sentinel. This guarantees
that the test A[i] < x must eventually fail.
- If x is found in A[i]:
- We perform i + 1 comparisons against x.
- Plus 3 more.
- If x is not found:
- We must do i + 4 comparisons if A[i - 1] < x < A[i].
- We must do 4 comparisons if x < A[0].
- And we must do n + 3 comparisons if x > A[n - 1].
- So we have again saved about half the comparisons by using a
sentinel, and now we can end the loop early if we find a value greater
than or equal to x.
To Index
Previous
Next