I'm assuming that the one if statement is not supposed to be on the same line as the comment... if that is intentional it does change things up somewhat :)
int search(int a[], int l, int r, int x) {
1. int m = (l+r)>>1;
2. if (l > r) return -1; // not found
3. if (a[m] == x) return m;
4. if (a[m] > x) return search(a, l, m-1, x);
5. return search(a, m+1, r, x);
}
I am also assuming T(n) means you are looking for the worst-case scenario (eg. the number you are searching for was the last one you checked, or was not found at all). The most straight forward way of solving these is to simply trace it through line by line, keeping track of the values of the variables in a table, until you notice a pattern emerge. Now, note that finding a pattern by itself never proves that the pattern you found is actually correct, but it will give you a good place to start, and will frequently (but not always) even yield the correct solution to the problem.
So, that being said, here's the gist of how I traced through it, minus a table with variable values like r/2, r/4, etc.
- m is being set to halfway between l and r in line 1 (I suppose doing it with a bitshift is more efficient...)
- The worst case would definitely involve running the search again. However, you can tell that this time either r is going to be halfway closer to l (line 4) or l is going to be halfway to r (line 5)
- m is being set to halfway between l and r again, and so on, until m cannot be cut in half anymore (this will occur in line 2 where l > r)
m keeps getting cut in half again and again until it cannot get cut in half. This pattern implies that maybe (probably) T(n) = O(log2 n). If you need to prove its correctness you would need to do a more formal direct proof than a trace. You could use Master's Theorem to prove its correctness as well.
If you are going to be doing a lot of these or if you need to prove the correctness of these it may be worth your time to look up how Master Theorem works, as getting your mind around that will make these a lot easier.