 Hello and welcome back. In this lecture, we are going to look at techniques to search for elements in a given array. Here is a quick recap of some of the relevant topics we have already studied. We have looked at how to sort an array of integers. Specifically, we looked at selection sort and merge sort. And we have also seen how to count the number of basic steps using any of these techniques when sorting an array. We have also seen how to sort arrays of strings and other data types. And basically, we saw that the same techniques as used for sorting integers apply. It is just that we have to use an appropriate comparison operator. In this lecture, we will first look at how to search for an integer in a given array of integers. We will look at the simplest technique which is linear search. Then we will look at a slightly more sophisticated technique called binary search. We will of course look at their implementations in C plus plus as well. And finally, we will discuss how to search strings and other data types as well. So, what is the searching problem? Suppose you are given an array of integers and a candidate integer n. And you are asked, is this integer n present in the array a? So, it is really a yes no question. A more interesting version of this question is that if n is present in a, then return its index in the array a, otherwise you return minus 1. And of course, once you know what the return value is, you can figure out the yes no answer as well. So, here is an example. Here is an array a of integers. The elements are a 0 through a 5. And here is this the integer that we want to search. And in this case, if I want to check whether 27 is present in this array, the answer I should get is the index of 27 in this array. 27 is indeed present here. So, my searching technique should return 4 that is the index of 27 in this array. On the other hand, if I give 23 which is not present in this array, it should return minus 1. Instead, if I give 24, note that there are two occurrences of 24 in this array. So, it could either return 0 or it could return 5. And what we will say is that in case of multiple matches, the index of any one of them can be returned. Well, so the simplest technique to do this search is basically linear search. You check each element of the array, you stop on finding the first match and then you output the index at that position of the array. And if you have exhausted the array and not found the match so far, you return minus 1. So, here is a simple C++ program for doing linear search. This is the main function. Here I have my declarations. So, here is my array A containing up to 100 integers in which I want to search for a given integer. So, I ask for the size of the array and read in the size of the array from the user. And then I do some input validation. We have seen this earlier. And then I ask the user to given all the n positive integers in the array. So, in this case this program is asking the user to give only positive integers in the array. We will soon see why we are saying only positive integers. It simplifies a few things later on. And then we have a simple for loop in which I read in all the elements into the array A. So, the elements are now stored in A0 through AN minus 1. Now, after the declarations are provided, the inputs are read and validated. Here I want to do my linear search. So, here is my search element. And here is the index at which I want to say whether the array A contains the search element. I have a do while loop here. And note that I have said do while true. So, basically this is an infinite loop. And here I tell the user that you give me the element to search. And if you give me minus 1, then I will exit. So, really if the user wants to exit from this do while loop, the user needs to provide minus 1 here. And then I read in the search element. And if the search element is minus 1, I break from this loop and exit from the function main. On the other hand, if the search element is not minus 1, I call this linear search function which takes the array A, takes the number of elements in the array A and the search element. And it returns me an index which is minus 1 if the search element was not present in the array. Otherwise, it gives me the index in the array A where the search element was present. So, knowing the value of index, I can print out an appropriate message over here. Now, how would the function linear search look like? Here is how it would look like. It basically iterates through the array A from A 0 through A n minus 1. Whenever it finds something which is equal to the search element, it returns that. If it exits this for loop without finding any search element, it returns minus 1. So, this is simple. Now, how many basic steps were involved in doing this search? Well, as a basic step, we needed to compare an element of the array A with the element that I am searching for. And I needed to increment an index. So, it is very easy to see that if I have an array A of size n, then at most n basic steps may be needed to search for a given element in that array. In the worst case, I might need to look at all the elements in the array before I can decide whether the element is present in the array or not. Now, the question is can we do better than this? Can we do better than n basic steps? So, here is a particular way of going about solving the searching problem. So, here is our initial array in which we want to search. Let us first sort this array and in this particular case, I have sorted it in decreasing order. We have already seen from our previous lectures how to sort an array of integers in decreasing order. And let us say, I am looking for this integer 18 over here. Now, once I have sorted the array in decreasing order, what I could do is I could say, let me search for this integer 18 in the sorted array. And let me find out what its position would be in this sorted array. So, note that I have slightly modified the problem. Instead of searching in the original array, I am now searching in the sorted array. So, the index that I expect to be returned is the position in the sorted array of this number if it is present in the array. So, what I am going to do first is, I am going to look at the mid position in the array and why am I looking at the mid position? Because once I know what the value of this mid position is, since this is sorted in decreasing order, I know this part of the array must contain elements greater than equal to 24 and this other part of the array must contain elements less than or equal to 24. So, if I now compare and find out that the element that I am searching for is less than 24, I know that the top part of the array is absolutely of no use. I can continue searching only in the bottom part of the array. How do I continue searching there? Once again, I look for the mid element here. So, in this case of course, there are three elements. So, I have chosen the mid element to be this. And once again, since this is sorted in decreasing order, this part of the array has elements greater than equal to 18. This part of the array has elements less than or equal to 18. And now, I again compare the integer I am searching for with the mid element. In this particular case, it happens to match the mid element and so we are basically done. So, basically the general idea is that if I give you a sorted array and let us say this sorted array was in increasing order. We have just seen that we could do this better version of sorting with an array that is sorted in decreasing order. But we could also of course, do it if the array was sorted in increasing order. Let us see what would happen if the array was sorted in increasing order. So, we are given this array. We are given a search element m and what we want to do is we want to check whether m is present at half way in this range of indices of the array. If it is so, then we return that n by 2 index we are done. Otherwise, if m is less than the element at the position n by 2, then since this array is sorted in increasing order, we know that we only need to look at the first part of the array from 0 to n by 2 minus 1. Otherwise, if m is greater than a n by 2, then we only need to look at the second half of the array, the later part of the array which is from a n by 2 to a n minus 1. And if the array a has only one element and m does not match that, then of course, we can return minus 1. So, as you will notice that I am really using a recursion over here under some condition instead of searching in the whole array from 0 through n minus 1, I am searching in the indices 0 through n by 2 minus 1 or n by 2 through n minus 1. So, this is really recursion and these are the two termination cases of the recursion. Once I find the element, I return no more recursion or if there was only one element and they could not find a match, then I know that the element I am searching for is not in the array. So, I can return minus 1. So, this technique of basically dividing the whole array into halves and then using a comparison to determine which half you should search in is also called binary search. So, here is a simple animation of binary search in action. Suppose, I have an array a sorted in increasing order as we just discussed, this is the midpoint of the array and let us say the search element is less than the value of the element at the midpoint. So, this entire second half can go and I am only left with the first half of the array. Once again I find the mid position and if now the search element is greater than the value of a at this mid position, then the first half can go and I am only left with this part here. Note that this part here is some intermediate part in the whole array and that happened because I first eliminated this half and then from the remaining half I again eliminated one half of it. Now, once again this is the mid position and maybe the search element is again less than a mid. So, that part of the array would go and only this would remain. This is the mid position, if there are only two elements, then I could choose any one of them as the mid position and let us say the search element is less than a mid again. So, I am left with only one element and now maybe the search element equals the value of a at that position and we are done. So, here is how binary search might look in C plus plus, here is my binary search function. As a precondition, I have assumed that a start through a n minus 1 is sorted in increasing order. You could also do this for decreasing order as we have already seen earlier. The post condition is that if the search element is present in a start through a n minus 1, then we return its index otherwise we return minus 1. Note that unlike linear search, I need to specify here the start index and the end index of the part of the array a that we are searching in and of course, we have the search element. As the first part of this function, we basically have one of the termination cases. So, there is exactly one element and if it matches the search element, we return the start position, the start index, otherwise we return minus 1. And in the other part of the function, we basically compute the mid point and once again search if a of mid matches the search element, then we return the mid index. Otherwise, what do we do? We find out which half of the array we should resume our search in. So, if a mid was less than the search element, then I know that I must search in the part of the array after a mid because this is sorted in increasing order. So, I do binary search on the part of array a from mid through end and whatever index it returns, I return that back. Otherwise, I do binary search on the part of the array from a start through a mid minus 1 and return whatever index it returns. So, that is as easy as it. What about searching other data types? Well, it is basically exactly the same techniques. You will have to first sort the array. So, for that we know from our previous lecture that we have to use an appropriate comparison operator. For strings, we had used this function called lex earlier. For other data types, I might need to design some custom comparison operator and then once I have sorted the array, I can use the same comparison operator for doing my binary search and decide which half of the array to recurs on based on the output of the comparison operator. How many basic steps were required in binary search? Well, if Tn is the maximum count of steps when searching for an element in an array of size n, it is clear that in one step, I am doing a comparison which can be thought of as one basic step and then I am basically searching in an array of size n by 2. So, the number of steps needed to search in an array of size n by 2 would be T of n by 2. So, this is coming from the recursion and this is the one comparison that I used to decide which half of the array I should now resume my search in and of course, when the array has just one element, the count of basic steps is 1 and using standard techniques, if you solve this recurrence relation, you get Tn is roughly the ceiling of log n base 2. So, note the difference with linear search where Tn was n. Now, Tn is log n base 2. So, this has exponentially fewer basic steps. Binary search uses exponentially fewer basic steps than linear search. So, in summary, we looked at techniques to search in an array of integers. We looked at linear search and binary search and we saw that having the array sorted really helps in searching. If the array is unsorted, we have no other way, but to do linear search which is not very efficient we have seen and we also saw how to count basic steps in searching and we have seen that as long as we have a comparison operator, we can really use the same techniques to search in an array of any other data type. Thank you.