 So, this one really is you know kind of an add on to whatever we have studied. So, we have studied about sorting integers now I am asking can we sort strings or other data types and since all of you have already gone through the slides let me just go to the primary slide here. So, you know instead of integers now I have some strings like names of students and I want to lexicographically sort them which means I want to sort them in the dictionary order. So, any name starting with A should appear before any name starting with B if there are two names starting with B then I should look at the next letter and if I appears before you then that name should appear before the other name. So, that is the lexicographic sorting and how do we do this? So, you know this is just like selection sort, but applied on strings what we are doing is we are saying that remember in selection sort what did we do? We basically looked at the entire array found out the element which should go to the topmost position. So, how did we do this? We looked at this entire array and we found the maximum element and we put it in its rightful position. So, here instead of the maximum element we will find the lexicographically first element the element that appears first in the dictionary order. So, that is Anu in this case. So, we put it in the topmost position and then we have the remainder of the array which is still left to sort. In this array we will find again the lexicographically first element first that appears in the dictionary order we will put it in the next position and then we will have the remainder of the array to sort. So, it looks like if we can select the lexicographically first element in an unsorted sub array then we can just apply our same idea of selection sort and actually lexicographically sort this array of strings. Because the basic idea is to choose what should be the first element. So, if I can figure out from a given array of strings what should appear first in the dictionary order then I am done. Now, how did we find out the maximum element in an array of integers we really iterated over that array we compared every for every pair which element was greater than that. So, here also we are going to do the same thing we are going to iterate over the array and we are going to compare pairs of elements right. So, basically what we really need is a mechanism of comparing a pair of strings and figuring out which one of them should appear before the other in the dictionary order. So, that is the lexicographic ordering right. So, if we can do that then in a given array I can just iterate over that array and find out what is the lexicographically first string move it to the topmost position and then just repeat it for the remainder of the array right and I would automatically end up sorting the array in lexicographically. So, let us assume for the time being that this function which tells us whether one string is lexicographically before the other is given to us we are going to study about you know strings and character arrays and then we will see how to do this it is not very hard to do, but let us for the time being assume that we are already given a function which takes two strings. So, here I have represented here I have written strings string is a special data type that is available in C++ however if you want to use a them as character arrays that is fine you can use them as character arrays and what this function is going to do is it is going to return true if the first string is lexicographically earlier than the second string otherwise it will return false. So, let us not worry about how this function is implemented this is the contract view of function I just know its preconditions and post conditions and let me use that in the algorithm for selection sort. So, basically in this loop if you remember this was the main loop for selection sort we had current top going from 0 to n minus 1 which was telling us the unsorted part of the array and there we found the index of the maximum element earlier here we are going to find the index of the lexicographically first element and then we are just going to swap it with current top it is as simple as that how do we find index of the lexicographically first element we just iterate over the part of the array and earlier we had compared whether a i was greater than a current index max now we will just check if a i is lexicographically earlier than a current index max. So, this is the comparison current whatever current lex first index so this is the only difference between the two instead of using the greater than comparison over integers now I am using the lexicographically ordering over two strings and that is it and is it the case that we just got lucky with selection sort and this would not really work if we try to do merge sort if you go and look at what we did for merge sort really in merge sort when we are trying to merge two sorted sub arrays we looked at the two elements pointed by the two arrows and we figured out which one of them should appear before the other and we put that in the sorted array. So, it is really that same question given two two elements which one should appear before the other. So, if there were two strings I can use the same lex earlier function to find out which one of them should appear before the other right so that is given here. So, I will not go through that because this is really the same thing except that in this merge thing whenever we were comparing two elements to figure out which one of them should go earlier in the sorted array we are now going to have this comparison if a j is lexicographically earlier than a i then I will copy a j to temp a otherwise I will copy a i to temp is that clear the rest of it is absolutely the same and of course you should sort of rename your variables accordingly so that they they are more meaningful earlier we were sorting integers so it was index of max so maybe we should now call it index of lexicographically first or something right. And what do we do if we have arrays of other data types let us say floats doubles or other more complex data types that we are going to study soon it turns out that we really have to do the same thing we just have to come up with an ordering function for two elements of the data type for two objects of the data type. And as long as we can order two objects of the data type we can do selection sort selection sort is really finding the earliest element in a given array so if you just keep comparing pairs of elements you will find the earliest element and merge sort when you are merging you have to find the earliest of two given elements so as long as you have an ordering operator it is fine okay good so and this is certainly not the end of sorting I mean there are far more interesting techniques used for sorting so I have just listed some of them here you know I encourage all of you to at least spend five or ten minutes looking up Wikipedia on these things very interesting area of study what we have studied is selection sort which is probably one of the simplest but not so efficient sorting techniques and merge sort which is actually a real-life sorting technique in fact merge sort is used in a lot of practical applications because it has a very good running time as we just saw right are there any doubts in this part of the lecture which is the most efficient sort that's a good question of the different sorting techniques of selection sort and merge sort the answer is clear so yeah so what you can show is that if you do a comparison based sorting where you're comparing two elements and then trying to figure out which goes earlier or the other then you need a minimum of n times log n base two basic steps this can be proven mathematically in so any sorting technique if it is using comparisons to figure out which should go before the other doesn't for example selection sort also use that merge sort also use that quick sort hip sort insertion sort all of these techniques are going to use that so any comparison based sorting technique must use in the worst case n times log n base two comparisons so in some sense this is optimal for the worst case already right however the average case running time may be much faster for so these are all the worst case running times in the worst case you'll have to have this many steps so the average case running time could be faster for some kinds of data you know for example if I know my data is almost sorted but there are just some elements which are not sorted then I could come up with a different technique which may actually just quickly find out those things so there are more sophisticated algorithms which will work for special kinds of data if you know some properties of the data we can make it work for those but if you're using comparison based sorting and if you want to sort the entire array no assumptions about the data in the array one can mathematically show that you need in the worst case at least n times log n base two comparisons so in the worst case much sort is already but in practice you know for example quick sort that's why it's called quick sort usually turns out to be faster than so we're not going to cover quick sort at least in the lectures it turns out to be usually faster than much although in the worst case the behavior is the same good question okay so now we look at the third one which is actually this is more like you know once you have a sorted array you can do so many nice things with that so you know let me quickly go through this so the searching problem is very simple you're given an array of integers you're given a particular integer n let us say and you're you're asking is n present in a right and what we want is if n is indeed present in a we want you to give us the index in a where n is present otherwise we want you to return minus one so here are some sample examples if this is my array and if n is 27 then I should return 4 because a 4 is 27 right and if this is my array and n is 23 then I should return minus one because minus one is because 23 is not in the array and if I'm asking for 24 there are 2 24's in this array so I could return either one of them so it's okay to return any one of the matching now the simplest way to do this is you know let me directly go to the code is to actually do what is called a linear search so linear search means you just iterate over the array and if the current element matches the search element then you say yes I found it otherwise you say minus one I've gone through the entire and have not found the right but how many basic steps is it going to take if the array has n elements it's clear that will take n basic steps you really have to look at every element in the array in the worst case right so basic steps is n and the question is can we do better in order to do better what we'll do is we'll first take the array and then we'll sort it okay so that that is the original array and this will sort it so here let me try to also mention this that given an array when we are searching elements in the array so in a lot of real life problems what's going to happen is you're given one array maybe of size 1 million and then maybe you want to make another 1 million searches on that array so that array stays the same but you want to make a lot of searches on that array you want to find out whether some element is present some element is not present so you want to ask questions about the presence or absence of elements in the array a very large number of times right so given an array the total number of searches we might make on the array might be very large it's not usually not just one element so what we are saying is given the array let's pay this one time price of sorting the array and then can we speeden up each of the searches that we're going to do right so it's a one-time cost that we pay because after that we're going to make a lot of searches and after that we'll see if we can speeden up the search okay so what we will do is so in this example this was our sorted array and we'll first find out the middle element in this array so that's 24 and because this array is sorted now I have this guarantee that the part above it is greater than equal to 24 and the part below it is less than or equal to 24 so if I'm searching for 18 it absolutely does not make sense to search in this part because all elements here are greater than equal to 24 so we'll just throw that part out from our consideration and focus our search in this part of the array but now it is again a smaller but simpler problem I'm trying to search an element in a smaller array so I'll use the same technique I'll go to the middle element and I know that this the part above it is greater than equal to 18 because it is sorted in decreasing order the part below it is less than or equal to 18 and in this case the middle element is indeed 18 so I'm done I found the element that I was looking for in general I may have to you know further select which half of the sub array if the middle element doesn't match I have to figure out which half of the sub array should I focus my search on but in any case at every step you are keeping on halving the size of the array right so at at no step are you continuing with the same size of the array in the next step so let me directly show this illustration so suppose this is an array sorted in increasing order and that is the midpoint let us say and we have a search element and we've figured out that the search element is less than a minute now remember I'm just making comparison with only the mid element right so this is just one comparison there I make a comparison with the mid element figure out that the element I'm searching for is less than a minute and because this is sorted in increasing order therefore there is no point searching in this part of the array because all of those will be greater than equal to a minute so I'll just remove that part and say that now I want to search in this part of the array right so again I'll find the mid element and let us say now I find that search element is greater than a minute this a minute so then there is no point searching in this part because this is sorted in increasing order so I'll throw out that part and I'll restrict my search to this part again I'll find the mid I'll ask the search element less than or greater than mid the search element is equal to mid I'm done I found it otherwise I'll again throw out some part of the array and just keep doing this until I found the element right so at every step we are having it and that's the basic idea so this this way of searching for an element is also called binary search and as you just saw what we're going to do is so in binary search we're going to take an array a and a start through a and minus one as you just saw I had a large array and initially I was interested in this entire array then I was interested in one half of the array then I was interested in some other half of the array and so on so at any point of time I'll have to tell to this function which part of the array is am I interested in so the start and end basically do that job I'm interested in the part of the array between the indices start and end minus one and I'm interested in searching for this element search element and we must have the array sorted so in what order are we going to assume it to be sorted let's assume that it is sorted in increasing order and at the end if the search element was already present in this array then I want its index to be returned otherwise I want minus one so what do we do we look at the termination case first if the array has just one element right then if that element already matches my search element then I can return its index that element does not match my search element it's minus one because my array of interest just has one element so either that element is the search element or that element is not the search the other case is when my array is of size greater than one so what I'll do is I'll figure out its midpoint so that is mid is start plus end over 2 and then I'll check whether a mid is indeed equal to search element if a mid is equal to search element I'm done I can return right otherwise if a mid is not equal to search element then a mid is either greater than search element or less than search element so if a mid is less than search element then because this array is sorted in increasing order I can now focus on the part of the array from mid through n minus one only on elements greater than a mid right otherwise I'll focus on the part from start through mid minus one it's a part continuing less than m the elements less than a mid right and that's it that's what binary search is about how do we search search other data types it's exactly the same way as you can see the crucial step here was I checked equality which I can do for any data type and then I needed to make this comparison if a mid is less than search element or a mid is greater than search element so once again if I have a comparison operator for strings or for whatever other data type you want I can actually do binary search and in fact the same comparison operator that you're going to use for searching for sorting you can use that same operator for searching to do the binary search right good how many basic steps so if you look at the algorithm if the arrays of size one of course there's just one basic step right and if the arrays of size n then we first make a comparison with the we compute the index of the mid element we compare with a mid so I'm calling that a basic step so that is one so computing the index of the mid element comparing with a mid that is one basic step and then determining which half of the array I should search in but that is just half of the array so it is Tn over 2 so Tn is Tn over 2 plus 1 the termination cases T1 is 1 and the solution for this is log n okay so this is log n the earlier linear search was n so this is exponentially better than the other one and in fact this is as efficient as you can get you know so one can show that if you're searching for an element in an array in the worst case you need to make at least log in comparisons so we'll start the video quiz I hope all of you have the answer sheets okay so recap quiz first question is which of the following is true of the implementations of selection sort and merge sort as taught in class we have just now covered merge sort we have seen at selection sort we we also looked at the code for selection sort so as taught in class which of the following is true both implementations were recursive only the implementation of selection sort was recursive only the implementation of merge sort was recursive and none of the implementations were recursive right as taught in class which of them was recursive okay it's an easy one so let's go to the next one so consider an integer array of size n you already know the number of basic steps to sort a by selection sort you know the number of basic steps to sort a by merge sort so if I divide this and compute the ratio this grows roughly linearly with which of these quantities n over 2 raised to n n over log n log n over n and n squared over log n the growth of this ratio with n will be roughly linear with which one of these quantities so if you know the number of basic steps you can just divide them and you can see which are the dominating terms there and you can compute this ratio by using an appropriate comparison operator merge sort or selection sort can be used to sort an array of which data types integers characters strings and double was more than one answer may be correct in any of the questions okay both question binary search can be used to efficiently search for an element in an unsorted array an array sorted in ascending order an array sorted in descending order all of the above okay the last question so in a recursive implementation of binary search as we just saw a few minutes back what happens in the termination case so it always finds the search element in the array it may not find the search element in the array the termination case may happen when the size of the sub array being searched is greater than one and none of the above so this is about the termination case of binary search in the termination case does it always find the search element may not find the search element and in the termination case can the size of the sub array being searched be greater than one okay so T is if you could please collect the answer sheets and bring them