1. Create a function based on sequential search and a program that will test it.
Use method 3 of Appendix C to generate a list of random numbers in the range of 1 to N that you can use for your search, where N could be any number between 100 and 1000. Your program should have a global counter, which should be initialized to zero at the beginning of the program and 2.3.1 EXERCISES
■
should be incremented just before the key comparison in your sequential search routine. Your main program should then call sequential search for each number between 1 and N. After doing this, the total count of compar- isons divided by N will be the average number of comparisons done by sequential search.
2. Repeat Step 1 for binary search, using an ordered list.
3. Write a report that compares your output from parts 1 and 2 with the results you would predict based on the analysis in this chapter.
C H A P T E R
3
Sorting Algorithms
PREREQUISITES
Before beginning this chapter, you should be able to
•Read and create iterative and recursive algorithms
•Use summations and probabilities presented in Chapter 1
•Solve recurrence relations
•Describe growth rates and order GOALS
At the end of this chapter, you should be able to
•Explain insertion sort and its analysis
•Explain bubble sort and its analysis
•Explain shellsort and its analysis
•Explain radix sort and its analysis
•Trace the heapsort and FixHeap algorithms
•Explain the analysis of heapsort
•Explain merge sort and its analysis
•Explain quicksort and its analysis
•Explain external polyphase merge sort and its analysis STUDY SUGGESTIONS
As you are working through the chapter, you should rework the examples to be sure you understand them. It will be especially helpful to trace insertion
sort, bubble sort, shellsort, heapsort, merge sort, and quicksort using the lists [6, 2, 4, 7, 1, 3, 8, 5] and [15, 4, 10, 8, 6, 9, 16, 1, 7, 3, 11, 14, 2, 5, 12, 13].
You should trace radix sort using three buckets for 1, 2, and 3, and the list [1113, 2231, 3232, 1211, 3133, 2123, 2321, 1312, 3223, 2332, 1121, 3312].
Additionally, you should try to answer any questions before reading on. A hint or the answer is in the sentences following the question.
n this chapter, we will consider another class of fundamental algorithms from computing: sorting algorithms. Because of the significant time sav- ings of binary search over sequential search, software designers will fre- quently choose to keep information sorted so that searches can be done by binary or other nonsequential methods.
As in Chapter 2, we will work with a list of records, which have a special field called the key. All of our sort algorithms will sort the list into increasing order based on this key value. We will use standard comparisons with these keys with the full knowledge that when they are used, we might be comparing integers, strings, or more complex key types. For the sake of simplicity, we will assume that each of the values in the list is distinct, because the presence of duplicates will not significantly change any of the analyses that we do in this chapter. The reader should recognize that changing the comparison of keys would result in a different ordering. For example, if the less than and greater than comparisons are swapped, the list will be sorted in decreasing order.
The eight sorting algorithms discussed in this chapter are only a sampling of the possible sorts, but they exhibit a wide range of behaviors. The first, inser- tion sort, accomplishes sorting by inserting new elements into the correct place in a list that is already sorted. Bubble sort compares pairs of elements, swapping those that are out of order, until the list is sorted. Shellsort is a multi- pass sort that breaks the list into sublists that are sorted, and on each successive pass the number of sublists is decreased as their size is increased. Radix sort is a multipass sort that separates the list into buckets, each pass using a different part of the key. Heapsort builds a binary tree with list elements so that each node has a value larger than its children. This places the largest element at the root so that when it is removed and the heap is fixed, the next largest element moves to the root. This is repeated until all of the elements are back in the now-sorted list. Merge sort starts with two sorted lists and creates one sorted list by merg-
I
ing these two. Quicksort is a recursive sort that picks a pivot element from the list and then subdivides the list into two parts that contain the elements that are smaller and larger than the pivot.
The last sort considered is different in that it works with lists that are so large that they cannot be reasonably held in a computer’s memory all at once. This external sort works with groups of records in sequential files and is designed to limit the file accesses, which would be an operation much slower than a com- parison. The reader should note that even with expanded memory in today’s computers, holding all of a database’s records in memory at once may be possi- ble but may incur delays due to virtual memory swapping. In this case, even though writing to disk files is not part of the algorithm, the reliance on virtual memory incurs the same cost because swaps are written to temporary disk files by the operating system.