 Hello and welcome. In this lecture, we are going to see how to sort arrays of strings and how the same techniques can be generalized to sort arrays of other data types as well. Here is a quick recap of some of the relevant topics that we have already studied. We have looked at the sorting problem in general. Specifically, we have seen how to implement selection sort and merge sort in C++ for arrays of integers. And we have also studied how to count the number of basic steps when sorting an array of integers. In this lecture, we are going to see how to sort arrays of strings and we will see that the same technique basically generalizes to sort arrays of other data types as well. In fact, all of these techniques use the same underlying principles, whether you are sorting integers or strings or other data types. There is only very minor difference in C++ programs that actually implement sorting for these different data types. We will also take a very quick look at some other techniques for sorting. We are not going to go into the details for other techniques for sorting, but it is important to know that there are other techniques for sorting beyond what we have learned in the past few lectures. So here is some food for thought. We have looked at techniques for sorting arrays of integers, but what if we wanted to sort arrays of other data types like floats, doubles, strings, more complex data items. So well, as you might have already guessed that the technique that we have used for sorting arrays of integers should work almost unchanged for sorting arrays of floats and doubles as well. However, would it work for sorting arrays of strings and what about more complex data items? So the question is that do we need to reinvent sorting techniques based on what are the data types that we have in our arrays? Fortunately, the answer to that is no. Almost the same techniques that we have studied for sorting integers are also going to work in these other settings. So let us quickly recap how we went about sorting integers. Here is an unsorted array of integers and we have seen techniques how to convert it into a sorted array of integers where the sorting is in decreasing order. Well, in selection sort where we wanted to sort the array in decreasing order, how did we go about our business? What we did is we first selected the largest element in the unsorted sub array. Since we want decreasing order, we selected the largest element. Then we put this selected element at the top of our sub array of interest and then we said that we have a remaining problem and we wanted to sort the remaining unsorted sub array using the same technique. And if you recall, this was the C++ code for doing selection sort for integers. We basically had a simple loop here in which we said that at any point of time, a current top through a n minus 1 is the unsorted array and the value of current top kept increasing from 0 through n minus 1. And in each iteration of the loop, we found out the index of the maximum element. Why was it maximum? Because we wanted to sort the array in the decreasing order. So we wanted to find the index of the maximum element in the part of array a between indices current top and n minus 1. And we found out that index and just swapped the elements of array a at current top and current max index. And we just kept iterating through this when current top finally becomes n. We know that the array is sorted. Now how did this function find index of max look like? Well, this is how it looked like. We have already studied this in an earlier lecture. There is a simple loop here which iterates from the start to the end of the sub array of interest. And in each iteration, it checks where the current array element is greater than equal to the currently maximum array element that has been seen. Why are we using greater than equal to? Because we wanted to sort there in a decreasing order. And if the current element is indeed greater than equal to the current maximum element seen so far, we updated current max index with the current index in this loop. And finally, we returned current max index. Well, the question is can we use the same ideas to sort strings? Suppose instead of an array of integers, I had an array of names like Ravi, Tejas, Anu, Biju, Banti and Surya. And I wanted to sort them in the lexicographic order or in the dictionary order. So, the name that would appear first in the dictionary Anu should appear at the top of the sorted array. The name that should appear next Biju should appear next and then Banti, Ravi, Surya and Tejas. So, the question is can we use the idea that we used for sorting integers to actually sort arrays of strings as well? Well, let us see how we might actually use something like selection sort, same idea as we did for selection sort and integers. If we use the same idea to do a lexicographic sorting of this array of names, how might it look like? So, we have this unsorted array of names and then we wanted to sort them in lexicographic order. So, we would find the lexicographically first element in this unsorted array. Here it is Anu and then we would put the selected element at the top of the sub array of interest for us now. And then we will be left with the remainder of the array and we want to sort this remaining unsorted sub array using the same technique. So, well it looks like if we can select the lexicographically first string in an unsorted sub array, we can just repeatedly execute this process and end up sorting this array of strings using the same ideas as we used for sorting an array of integers using selection sort. Now, how do we select the lexicographically first element in an array of strings? The answer is pretty much the same as we did for integers. We basically iterate over the array and keep comparing or ordering pairs of elements and we just keep track of the lexicographically earliest element that we have seen so far. So, what this means is that if we could have a function which could lexicographically compare a pair of strings, then we can indeed iterate over this unsorted array and use this function to find the lexicographically earliest string. And once we have this facility to do this, we can actually use selection sort to actually sort an array of strings. This looks wonderful. So, all that we need is the ability to compare two strings and find out which is lexicographically earlier. Now, how are we going to do this? For the time being, let us assume that we have a function available to us. Let us call it lex earlier, it takes in two strings, recall string is a C plus plus data type. So, it has two strings as input parameters and it returns a Boolean value and the return value is true if and only if string S1 appears lexicographically before S2. Now, we will see later when we study strings, how to implement the body of this function, but for the time being, let us just take this contract view of this function. So, if I use that function, here is how selection sort in C plus plus for strings might look like. We have almost the same program that we saw earlier, except that now we are going to sort an array of strings. Instead of having current max index earlier, I now have a variable which says current lexicographically first index and instead of finding index of the max element earlier, now I call this function which finds the index of the lexicographically first element in the current unsorted part of the array which is from current top to n minus 1. And then how does find index of lex first look like? Well, it is pretty much the same that we had earlier for find index of max, except that we are now going to pass an array of strings as an input parameter. We are going to use this variable called current lex first index instead of current max index, current index of max. And then we are going to simply iterate in this loop and we are going to use this function that we have just seen lex earlier to figure out if the current element of the array appears lexicographically earlier than the current lexicographically earliest element that I have already seen. And if so, we update current lex first index to i and iterate. Finally, when this function returns, we have the current lex first index, the index of the lexicographically first element in the part of the array between start through n minus 1. Now, it looks like we are now able to do selection sort with strings, but did we just get lucky with selection sort? Can we sort strings using merge sort as well? If I give you this comparison function lex earlier, let us see what were the steps in merge sort? We took an array of size n and divided into two sub arrays each of size roughly n by 2. And then we sorted each of these sub arrays recursively using the same technique. And the crucial step was to merge two sorted sub arrays each of size n by 2 to create one sorted array of size n. So, here is how our C++ program for merging sorted sub arrays of integers looked like. We basically had a merging loop in which we determined whether an element from the first sorted sub array or the element from the second sorted sub array should appear next in the overall sorted array. And then once we have determined whether the element should come from this sorted sub array or the other sorted sub array, we simply copied that element to this temporary integer array temp A. And at the end of it, we copied all the elements from temp A which are already sorted by now to the array A. The crucial part was this merging loop. How did it work? It was very simple when we have elements to see from both of the two sorted sub arrays. We just figured out which element should appear first and just copied that element to temp A and incremented the appropriate index. And if one of the sub arrays had already been fully seen, we just copied the elements from the other sub array. Now, if I were to do merge sort for strings, how would things look like? Well, it would be pretty much the same except that now these two sub arrays would be lexicographically sorted. I would have to pass a string of arrays as an input parameter to merge sorted sub arrays. I would have to have this temporary array of strings earlier, we had a temporary array of integers. And then at the end of it, we want the entire array between start and end minus 1, between indices start and end minus 1 to be lexicographically sorted. The merging loop would be almost the same that we saw earlier except that we have to use this lex earlier function over here. Now, what about arrays of other data types? I mean by now you must have figured out that what work for integers pretty much work for strings modulo that compares an operator. So, this should now work for other data types as well. All we need to do is to define an ordering function or operator. We use greater than equal to for integers when sorting in decreasing order. We use lex earlier for strings when sorting in lexicographically increasing order. We need to define a similar operator if I want to sort an array of another data type. The rest of it is exactly the same. Now, are there other sorting techniques out there? Yes, of course there are and these are some of the important other sorting techniques quick sort, heap sort, insertion sort. All of these can be implemented in C++. However, we will not have time to study all of these in this course. But I do want to point out that sorting is an extremely interesting area of study in computer science and in programming. So, in summary in this lecture, we looked at how to sort strings and we saw the key use of a comparison operator for lexicographic ordering between strings. We also saw that the same ideas basically can be used to sort other data types if I have an appropriate comparison operator. And we also had a very brief glimpse of sorting techniques beyond what we have already studied. Thank you.