Previous: 9.3 Arrays of Strings
Up: 9.1 Two Dimensional Arrays
Next: 9.5 An Example: Linear Algebraic Equations
Previous Page: 9.3.1 String Sorting and Searching
Next Page: 9.5 An Example: Linear Algebraic Equations
As seen in the last example, sorting an array of strings requires swapping the strings which can require copying a lot of data. For efficiency, it is better to avoid actual swapping of data whenever a data item is large, such as a string or an entire data base record. In addition, arrays may be needed in more than one order; for example, we may need an exam scores array sorted by Id number and by weighted scores; or, we may need strings in both an unsorted form and a sorted form. In either of these cases, we must either keep two copies of the data, each sorted differently, or find a more efficient way to store the data structure. The solution is to use pointers to elements of the array and swap pointers. Consider some examples:
int data1, data2, *ptr1, *ptr2, *save;We could swap the values of the data and store the swapped values in data1 and data2 or we could simply swap the values of the pointers:
data1 = 100; data2 = 200; ptr1 = &data1; ptr2 = &data2;
save = ptr1; ptr1 = ptr2; ptr2 = save;We have not changed the values in data1 and data2; but ptr1 now accesses data2 and ptr2 access data1. We have swapped the pointer values so they point to objects in a different order. We can apply the same idea to strings:
char name1 = "John"; char name2 = "Dave"; char *p1, *p2, *save;Pointers p1 and p2 point to strings name1 and name2. We can now swap the pointer values so p1 and p2 point to name2 and name1, respectively.
p1 = name1; p2 = name2;
In general, an array of pointers can be used to point to an array of data items with each element of the pointer array pointing to an element of the data array. Data items can be accessed either directly in the data array, or indirectly by dereferencing the elements of the pointer array. The advantage of a pointer array is that the pointers can be reordered in any manner without moving the data items. For example, the pointer array can be reordered so that the successive elements of the pointer array point to data items in sorted order without moving the data items. Reordering pointers is relatively fast compared to reordering large data items such as data records or strings. This approach saves a lot of time, with the additional advantage that the data items remain available in the original order. Let us see how we might implement such a scheme.
STRPTRS: Given an array of strings, use pointers to order the strings in sorted form, leaving the array unchanged.
We will use an array of character pointers to point to the strings declared as follows:
char * nameptr[MAX];The array, nameptr, is an array of size MAX, and each element of the array is a character pointer. It is then possible to assign character pointer values to the elements of the array; for example:
nameptr[i] = "John Smith";The string "John Smith" is placed somewhere in memory by the compiler and the pointer to the string constant is then assigned to nameptr[i]. It is also possible to assign the value of any string pointer to nameptr[i]; for example, if s is a string, then it is possible to assign the pointer value s to nameptr[i]:
nameptr[i] = s;In particular, we can read strings into a two dimensional array, names, and assign each string pointer, names[i] to the element of the pointer array, nameptr:
for (i = 0; i < MAX && gets(names[i]); i++) nameptr[i] = names[i];The strings can then be accessed either by names[i] or by nameptr[i] as seen in Figure 9.4. We can then reorder the pointers in nameptr so that they successively point to the strings in sorted order as seen in Figure 9.4. We can then print the strings in the original order by accessing them through names[i] and print the strings in sorted order by accessing them through nameptr[i]. Here is the algorithm:
while not end of file and array not exhausted, read a string store it in an array of strings and assign the string to an element of a pointer array
access the array of strings and print them out access the array of pointers and print strings that point to
The program driver, including a prototype for sortptrs() is shown in Figure 9.19.
It declares a two dimensional array of strings, names, and an array of character pointers, nameptr. It then reads strings into , and assigns each string pointer names[i] to nameptr[i]. The function sortptrs() is then called to reorder nameptr so the successive pointers of the array point to the strings in sorted order. Finally, strings are printed in original unsorted order by accessing them through names[i] and in sorted order by accessing them through nameptr[i].
The function uses the selection sort algorithm modified to access data items through pointers. It repeatedly moves the pointer to the largest string to the highest index of an effective array. The implementation of sorting using pointers to strings is shown in Figure 9.20.
The algorithm determines maxpos, the index of the pointer to the largest string. The pointer at maxpos is then moved to the highest index in the effective array. The array size is then reduced, etc.
Reordering of pointers, so they point to data items in sorted order, is referred to as sorting by pointers. When the data items are large, such as data records or strings, this is the preferred way of sorting because it is far more efficient to move pointers than it is to move entire data records.