SlideShare a Scribd company logo
Chapter 8
SORTING
1. Introduction and Notation
2. Insertion Sort
3. Selection Sort
4. Shell Sort
5. Lower Bounds
6. Divide-and-Conquer Sorting
7. Mergesort for Linked Lists
8. Quicksort for Contiguous Lists
9. Heaps and Heapsort
10. Review: Comparison of Methods
Outline Data Structures and Program Design In C++
Transp. 1, Chapter 8, Sorting 248 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Requirements
In an external sort, there are so many records to be sorted
that they must be kept in external files on disks, tapes, or the
like. In an internal sort the records can all be kept internally
in high-speed memory. We consider only internal sorting.
We use the notation and classes set up in Chapters 6 and 7.
Thus we shall sort lists of records into the order determined
by keys associated with the records. The declarations for a
list and the names assigned to various types and operations
will be the same as in previous chapters.
If two or more of the entries in a list have the same key, we
must exercise special care.
To analyze sorting algorithms, we consider both the number
of comparisons of keys and the number of times entries must
be moved inside a list, particularly in a contiguous list.
Both the worst-case and the average performance of a sort-
ing algorithm are of interest. To find the average, we shall
consider what would happen if the algorithm were run on all
possible orderings of the list (with n entries, there are n! such
orderings altogether) and take the average of the results.
Requirements Data Structures and Program Design In C++
Transp. 2, Sect. 8.1, Introduction and Notation 249 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Sortable Lists
To write efficient sorting programs, we must access the pri-
vate data members of the lists being sorted. Therefore, we
shall add sorting functions as methods of our basic List data
structures. The augmented list structure forms a new ADT
that we shall call a Sortable List, with the following form.
template <class Record>
class Sortable list: public List<Record> {
public: // Add prototypes for sorting methods here.
private: // Add prototypes for auxiliary functions here.
};
Hence a Sortable list is a List with extra sorting methods.
The base list class can be any of the List implementations of
Chapter 6.
We use a template parameter class called Record to stand for
entries of the Sortable list.
Every Record has an associated key of type Key. A Record
can be implicitly converted to the corresponding Key. The
keys (hence also the records) can be compared under the
operations ‘ < ,’ ‘ > ,’ ‘ >= ,’ ‘ <= ,’ ‘ == ,’ and ‘ != .’
Any of the Record implementations discussed in Chapter 7
can be supplied, by a client, as the template parameter of a
Sortable list.
Sortable Lists Data Structures and Program Design In C++
Transp. 3, Sect. 8.1, Introduction and Notation 250 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Ordered Insertion
An ordered list is an abstract data type, defined as a list in
which each entry has a key, and such that the keys are in
order; that is, if entry i comes before entry j in the list, then
the key of entry i is less than or equal to the key of entry j .
For ordered lists, we shall often use two new operations that
have no counterparts for other lists, since they use keys rather
than positions to locate the entry.
One operation retrieves an entry with a specified key from
the ordered list. Retrieval by key from an ordered list is
exactly the same as searching.
The second operation, ordered insertion, inserts a new
entry into an ordered list by using the key in the new entry
to determine where in the list to insert it.
Note that ordered insertion is not uniquely specified if the list
already contains an entry with the same key as the new entry,
since the new entry could go into more than one position.
New
entry
Ordered
list
Move
last entry
Move
previous
entry
Complete
insertion
cat
cow
dog
pig
ram
cat
cow
dog
pig
ram
cat
cow
dog
pig
ram
cat
cow
dog
hen
pig
ram
hen
(a) (b) (c) (d)
Ordered Insertion Data Structures and Program Design In C++
Transp. 4, Sect. 8.2, Insertion Sort 251 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Insertion Sort
Example:
cat
cow
dog
ewe
hen
ram
Initial
order
Insert
second
entry
Insert
third
entry
Insert
fourth
entry
Insert
fifth
entry
Insert
sixth
entry
sorted hen
cow
cat
ram
ewe
dog
cat
cow
hen
ram
ewe
dog
cat
cow
hen
ram
ewe
dog
cat
cow
ewe
hen
ram
dog
cow
hen
cat
ram
ewe
dog
sorted
.
.
.
.
.
.
.
sorted
unsorted
.
.
.
.
.
.
Main step, contiguous case:
UnsortedSorted
≤ current
> current
Remove current;
shift entries right
Before:
Sorted
current
UnsortedSorted
Sorted Unsorted
≤ current
Reinsert current;
> current
Insertion Sort Data Structures and Program Design In C++
Transp. 5, Sect. 8.2, Insertion Sort 252 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Contiguous Insertion Sort
template <class Record>
void Sortable list<Record> :: insertion sort( )
/* Post: The entries of the Sortable list have been rearranged so that the keys in all
the entries are sorted into nondecreasing order.
Uses: Methods for the class Record; the contiguous List implementation of Chapter
6 */
{
int first unsorted; // position of first unsorted entry
int position; // searches sorted part of list
Record current; // holds the entry temporarily removed from list
for (first unsorted = 1; first unsorted < count; first unsorted++)
if (entry[first unsorted] < entry[first unsorted − 1]) {
position = first unsorted;
current = entry[first unsorted]; // Pull unsorted entry out of the list.
do { // Shift all entries until the proper position is found.
entry[position] = entry[position − 1];
position−−; // position is empty.
} while (position > 0 && entry[position − 1] > current);
entry[position] = current;
}
}
Contiguous Insertion Sort Data Structures and Program Design In C++
Transp. 6, Sect. 8.2, Insertion Sort 253 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Linked Insertion Sort
With no movement of data, there is no need to search from the
end of the sorted sublist, as for the contiguous case.
Traverse the original list, taking one entry at a time and in-
serting it in the proper position in the sorted list.
Pointer last sorted references the end of the sorted part of the
list.
Pointer first unsorted == last sorted->next references the first
entry that has not yet been inserted into the sorted sublist.
Pointer current searches the sorted part of the list to find where
to insert *first unsorted.
If *first unsorted belongs before the head of the list, then insert
it there.
Otherwise, move current down the list until
first unsorted->entry <= current->entry
and then insert *first unsorted before *current. To enable inser-
tion before *current, keep a second pointer trailing in lock step
one position closer to the head than current.
A sentinel is an extra entry added to one end of a list to
ensure that a loop will terminate without having to include
a separate check. Since last sorted->next == first unsorted, the
node *first unsorted is already in position to serve as a sentinel
for the search, and the loop moving current is simplified.
A list with 0 or 1 entry is already sorted, so by checking these
cases separately we avoid trivialities elsewhere.
Linked Insertion Sort Data Structures and Program Design In C++
Transp. 7, Sect. 8.2, Insertion Sort 254 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
template <class Record>
void Sortable list<Record> :: insertion sort( )
/* Post: The entries of the Sortable list have been rearranged so that the keys in all
the entries are sorted into nondecreasing order.
Uses: Methods for the class Record, linked List implementation of Chapter 6. */
{ Node <Record> *first unsorted, // the first unsorted node to be inserted
*last sorted, // tail of the sorted sublist
*current, // used to traverse the sorted sublist
*trailing; // one position behind current
if (head != NULL) { // Otherwise, the empty list is already sorted.
last sorted = head; // The first node alone makes a sorted sublist.
while (last sorted->next != NULL) {
first unsorted = last sorted->next;
if (first unsorted->entry < head->entry) {
// Insert *first unsorted at the head of the sorted list:
last sorted->next = first unsorted->next;
first unsorted->next = head;
head = first unsorted; }
else { // Search the sorted sublist to insert *first unsorted:
trailing = head;
current = trailing->next;
while (first unsorted->entry > current->entry) {
trailing = current;
current = trailing->next;
}
// *first unsorted now belongs between *trailing and *current.
if (first unsorted == current)
last sorted = first unsorted; // already in right position
else {
last sorted->next = first unsorted->next;
first unsorted->next = current;
trailing->next = first unsorted;
} } } } }
Linked insertion sort Data Structures and Program Design In C++
Transp. 8, Sect. 8.2, Insertion Sort 255 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
last_sorted first_unsorted
last_sorted
Case 1:
Case 2:
head
Partially sorted:
*first_unsorted belongs at head of list
*first_unsorted belongs between *trailing and *current
head first_unsorted
head trailing current last_sorted first_unsorted
TraceoflinkedinsertionsortDataStructuresandProgramDesignInC++
Transp.9,Sect.8.2,InsertionSort256©1999Prentice-Hall,Inc.,UpperSaddleRiver,N.J.07458
Analysis of Insertion Sort
The average number of comparisons for insertion sort applied
to a list of n items in random order is 1
4
n2
+ O(n).
The average number of assignments of items for insertion sort
applied to a list of n items in random order is also 1
4
n2
+O(n).
The best case for contiguous insertion sort occurs when the list
is already in order, when insertion sort does nothing except
n − 1 comparisons of keys.
The worst case for contiguous insertion sort occurs when the
list is in reverse order.
THEOREM 8.1. Verifying that a list of n entries is in the correct
order requires at least n − 1 comparisons of keys.
Insertion sort verifies that a list is correctly sorted as quickly
as any method can.
Analysis of Insertion Sort Data Structures and Program Design In C++
Transp. 10, Sect. 8.2, Insertion Sort 257 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Selection Sort
Example:
Initial order
Colored box denotes largest unsorted key.
Gray boxes denote other unsorted keys.
Sorted
hen
cow
cat
dog
ewe
ram
ewe
cow
cat
dog
hen
ram
dog
cow
cat
ewe
hen
ram
cat
cow
dog
ewe
hen
ram
cat
cow
dog
ewe
hen
ram
hen
cow
cat
ram
ewe
dog
General step:
Unsorted
small keys
Sorted,
large keys
Maximum
unsorted key
Swap
Current position
Unsorted small keys Sorted, large keys
Selection Sort Data Structures and Program Design In C++
Transp. 11, Sect. 8.3, Selection Sort 258 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Selection sort:
template <class Record>
void Sortable list<Record> :: selection sort( )
/* Post: The entries of the Sortable list have been rearranged so that the keys
in all the entries are sorted into nondecreasing order.
Uses: max key, swap. */
{
for (int position = count − 1; position > 0; position−−) {
int max = max key(0, position);
swap(max, position);
}
}
Find maximum key:
template <class Record>
int Sortable list<Record> :: max key(int low, int high)
/* Pre: low and high are valid positions in the Sortable list and low <= high.
Post: The position of the entry between low and high with the largest key is
returned.
Uses: The class Record. The contiguous List implementation of Chapter 6.
*/
{
int largest, current;
largest = low;
for (current = low + 1; current <= high; current++)
if (entry[largest] < entry[current])
largest = current;
return largest;
}
Code for contiguous selection sort Data Structures and Program Design In C++
Transp. 12, Sect. 8.3, Selection Sort 259 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Swap entries:
template <class Record>
void Sortable list<Record> :: swap(int low, int high)
/* Pre: low and high are valid positions in the Sortable list.
Post: The entry at position low is swapped with the entry at position high.
Uses: The contiguous List implementation of Chapter 6. */
{
Record temp;
temp = entry[low];
entry[low] = entry[high];
entry[high] = temp;
}
Analysis and comparison:
Selection Insertion (average)
Assignments of entries 3.0n + O(1) 0.25n2
+ O(n)
Comparisons of keys 0.5n2
+ O(n) 0.25n2
+ O(n)
Selection sort Data Structures and Program Design In C++
Transp. 13, Sect. 8.3, Selection Sort 260 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Example of Shell Sort
Unsorted
Tim
Dot
Eva
Roy
Tom
Kim
Guy
Amy
Jon
Ann
Jim
Kay
Ron
Jan
Sublists incr. 5
Sublists incr. 3 3-Sorted
Dot
Eva
Tim
Roy
Tom
Recombined
Jim
Dot
Amy
Jan
Ann
Kim
Guy
Eva
Jon
Tom
Tim
Kay
Ron
Roy
List incr. 1
Guy
Ann
Amy
Jan
Dot
Jon
Jim
Eva
Kay
Ron
Roy
Kim
Tom
Tim
Sorted
Amy
Ann
Dot
Eva
Guy
Jan
Jim
Jon
Kay
Kim
Ron
Roy
Tim
Tom
5-Sorted
Dot
Amy
Jim
Jan
Ann
Guy
Amy
Kim
Jon
Ann
Kay
Ron
Jim
Jan
Guy
Eva
Kim
Jon
Tom
Kay
Ron
Tim
Roy
Jim
Dot
Amy
Jan
Ann
Kim
Guy
Eva
Jon
Tom
Tim
Kay
Ron
Roy
Guy
Ann
Amy
Jan
Dot
Jon
Jim
Eva
Kay
Ron
Roy
Kim
Tom
Tim
Example of Shell Sort Data Structures and Program Design In C++
Transp. 14, Sect. 8.4, Shell Sort 261 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Shell Sort
template <class Record>
void Sortable list<Record> :: shell sort( )
/* Post: The entries of the Sortable list have been rearranged so that the keys in all
the entries are sorted into nondecreasing order.
Uses: sort interval */
{
int increment, // spacing of entries in sublist
start; // starting point of sublist
increment = count;
do {
increment = increment/3 + 1;
for (start = 0; start < increment; start++)
sort interval(start, increment); // modified insertion sort
} while (increment > 1);
}
Shell Sort Data Structures and Program Design In C++
Transp. 15, Sect. 8.4, Shell Sort 262 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Lower Bounds for Sorting
How fast is it possible to sort?
Insertion sort
Selection sort
F
F
F
T
T
T
a ≤ b
b ≤ c
a ≤ b ≤ c
a ≤ c
b < a ≤ c
c < b < a c < a ≤ b a ≤ c < b
a < ba < c
b < c
c < b a < b
a < c
b ≤ c ≤ a c < b ≤ a
b ≤ c < a
b ≤ a < c impossible a < c ≤ b a < b < cimpossiblec ≤ a < b
F FT T F T
F T
a < b
F
F
F
T
T
T
F T
F T
a ≤ cb ≤ c
THEOREM 8.2 Any algorithm that sorts a list of n entries by
use of key comparisons must, in its worst case, perform at
least lg n! comparisons of keys, and, in the average case,
it must perform at least lg n! comparisons of keys.
Lower Bounds for Sorting Data Structures and Program Design In C++
Transp. 16, Sect. 8.5, Lower Bounds 263 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Divide and Conquer Sorting
Outline:
void Sortable list :: sort( )
{
if the list has length greater than 1 {
partition the list into lowlist, highlist;
lowlist.sort( );
highlist.sort( );
combine(lowlist, highlist);
}
}
Mergesort:
We chop the list into two sublists of sizes as nearly equal as
possible and then sort them separately. Afterward, we care-
fully merge the two sorted sublists into a single sorted list.
Quicksort:
We first choose some key from the list for which, we hope,
about half the keys will come before and half after. Call this
key the pivot. Then we partition the items so that all those
with keys less than the pivot come in one sublist, and all those
with greater keys come in another. Then we sort the two
reduced lists separately, put the sublists together, and the
whole list will be in order.
Divide and Conquer Sorting Data Structures and Program Design In C++
Transp. 17, Sect. 8.6, Divide-and-Conquer Sorting 264 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Start Finish
26 33 35 29 19 12
26 33 35 29 191219352926 33 12
26 33 35 29 26 29 33 35 19 12 22 12 19 22
22
29 19 12 22353326 26 29 33 35221912
Recursiontree,mergesortof7numbersDataStructuresandProgramDesignInC++
Transp.18,Sect.8.6,Divide-and-ConquerSorting265©1999Prentice-Hall,Inc.,UpperSaddleRiver,N.J.07458
Quicksort of 7 Numbers
Sort (26, 33, 35, 29, 12, 22)
Partition into (19, 12, 22) and (33, 35, 29); pivot = 26
Sort (19, 12, 22)
Sort (33, 35, 29)
Combine into (12, 19, 22, 26, 29, 33 35)
Partition into (12) and (22); pivot = 19
Sort (12)
Sort (22)
Combine into (12, 19, 22)
Partition into (29) and (35); pivot = 33
Sort (29)
Sort (35)
Combine into (29, 33, 35)
26
19 33
12 22 29 35
Trace and recursion tree, quicksort of 7 numbers Data Structures and Program Design In C++
Transp. 19, Sect. 8.6, Divide-and-Conquer Sorting 266 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Tim
TomDot
Amy Eva
Ann Roy
Kim
Guy Ron
Jon
Jim Kay
Jan
Tim
Tom
Dot
Amy
Eva
Ann Roy
Kim
Guy
Ron
Jon
Jim
Kay
Jan
Pivot is
central key.
Pivot is
first key.
Recursiontrees,quicksortof14namesDataStructuresandProgramDesignInC++
Transp.20,Sect.8.6,Divide-and-ConquerSorting267©1999Prentice-Hall,Inc.,UpperSaddleRiver,N.J.07458
Mergesort for Linked Lists
Interface method:
template <class Record>
void Sortable list<Record> :: merge sort( )
/* Post: The entries of the sortable list have been rearranged so that their keys are
sorted into nondecreasing order.
Uses: Linked List implementation of Chapter 6 and recursive merge sort.
*/
{
recursive merge sort(head);
}
Recursive function:
template <class Record>
void Sortable list<Record> ::
recursive merge sort(Node<Record> * &sub list)
/* Post: The nodes referenced by sub list have been rearranged so that their keys
are sorted into nondecreasing order. The pointer parameter sub list is
reset to point at the node containing the smallest key.
Uses: The linked List implementation of Chapter 6; the functions divide from,
merge, and recursive merge sort. */
{
if (sub list != NULL && sub list->next != NULL) {
Node<Record> *second half = divide from(sub list);
recursive merge sort(sub list);
recursive merge sort(second half);
sub list = merge(sub list, second half);
}
}
Mergesort for Linked Lists Data Structures and Program Design In C++
Transp. 21, Sect. 8.7, Mergesort for Linked Lists 268 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Divide Linked List in Half
template <class Record>
Node<Record> *Sortable list<Record> ::
divide from(Node<Record> *sub list)
/* Post: The list of nodes referenced by sub list has been reduced to its first half, and
a pointer to the first node in the second half of the sublist is returned. If the
sublist has an odd number of entries, then its first half will be one entry larger
than its second.
Uses: The linked List implementation of Chapter 6. */
{
Node<Record> *position, // traverses the entire list
*midpoint, // moves at half speed of position to midpoint
*second half;
if ((midpoint = sub list) == NULL) return NULL; // List is empty.
position = midpoint->next;
while (position != NULL) { // Move position twice for midpoint’s one move.
position = position->next;
if (position != NULL) {
midpoint = midpoint->next;
position = position->next;
}
}
second half = midpoint->next;
midpoint->next = NULL;
return second half;
}
Divide Linked List in Half Data Structures and Program Design In C++
Transp. 22, Sect. 8.7, Mergesort for Linked Lists 269 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Initial situation:
first 4 8 9
second 5 7
After merging:
4 8 9
5 7
3
1
3
1?
Dummy
node
combined
MergingtwosortedlinkedlistsDataStructuresandProgramDesignInC++
Transp.23,Sect.8.7,MergesortforLinkedLists270©1999Prentice-Hall,Inc.,UpperSaddleRiver,N.J.07458
Merge Function
template <class Record>
Node<Record> *Sortable list<Record> ::
merge(Node<Record> *first, Node<Record> *second)
/* Pre: first and second point to ordered lists of nodes.
Post: A pointer to an ordered list of nodes is returned. The ordered list contains all
entries that were referenced by first and second. The original lists of nodes
referenced by first and second are no longer available.
Uses: Methods for Record class; the linked List implementation of Chapter 6. */
{
Node<Record> *last sorted; // points to the last node of sorted list
Node<Record> combined; // dummy first node, points to merged list
last sorted = &combined;
while (first != NULL && second != NULL) { // Attach node with smaller key
if (first->entry <= second->entry) {
last sorted->next = first;
last sorted = first;
first = first->next; // Advance to the next unmerged node.
}
else {
last sorted->next = second;
last sorted = second;
second = second->next;
}
}
// After one list ends, attach the remainder of the other.
if (first == NULL)
last sorted->next = second;
else
last sorted->next = first;
return combined.next;
}
Merge Function Data Structures and Program Design In C++
Transp. 24, Sect. 8.7, Mergesort for Linked Lists 271 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Analysis of Mergesort
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 = n
22222 2 2 2
4 4 4 4
88
16
Lower bound: lg n! ≈ n lg n − 1.44n + O(log n)
Mergesort: n lg n − 1.1583n + 1,
Insertion sort: 1
4
n2
+ O(n)
Analysis of Mergesort Data Structures and Program Design In C++
Transp. 25, Sect. 8.7, Mergesort for Linked Lists 272 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Quicksort for Contiguous Lists
Interface method:
template <class Record>
void Sortable list<Record> :: quick sort( )
/* Post: The entries of the Sortable list have been rearranged so that their keys
are sorted into nondecreasing order.
Uses: Contiguous List implementation of Chapter 6, recursive quick sort.
*/
{
recursive quick sort(0, count − 1);
}
Recursive function:
template <class Record>
void Sortable list<Record> :: recursive quick sort(int low, int high)
/* Pre: low and high are valid positions in the Sortable list.
Post: The entries of the Sortable list have been rearranged so that their keys
are sorted into nondecreasing order.
Uses: Contiguous List implementation of Chapter 6, recursive quick sort,
and partition. */
{
int pivot position;
if (low < high) { // Otherwise, no sorting is needed.
pivot position = partition(low, high);
recursive quick sort(low, pivot position − 1);
recursive quick sort(pivot position + 1, high);
}
}
Quicksort for Contiguous Lists Data Structures and Program Design In C++
Transp. 26, Sect. 8.8, Quicksort for Contiguous Lists 273 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Goal (postcondition):
low
< pivot pivot ≥ pivot
pivot_position high
Loop invariant:
low last_small i
< pivotpivot ≥ pivot ?
Restore the invariant:
swap
last_small i
< pivotpivot ≥ pivot ?< pivot
last_small i
< pivotpivot ≥ pivot ?
Final position:
low
< pivotpivot ≥ pivot
last_small high
Partitioning the list: Algorithm development Data Structures and Program Design In C++
Transp. 27, Sect. 8.8, Quicksort for Contiguous Lists 274 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Partitioning the List
template <class Record>
int Sortable list<Record> :: partition(int low, int high)
/* Pre: low and high are valid positions of the Sortable list, with low <= high.
Post: The center (or left center) entry in the range between indices low and high of
the Sortable list has been chosen as a pivot. All entries of the Sortable list
between indices low and high, inclusive, have been rearranged so that those
with keys less than the pivot come before the pivot and the remaining entries
come after the pivot. The final position of the pivot is returned.
Uses: swap(int i, int j) (interchanges entries in positions i and j of a Sortable list),
the contiguous List implementation of Chapter 6, and methods for the class
Record. */
{
Record pivot;
int i, // used to scan through the list
last small; // position of the last key less than pivot
swap(low, (low + high)/2);
pivot = entry[low]; // First entry is now pivot.
last small = low;
for (i = low + 1; i <= high; i++)
/* At the beginning of each iteration of this loop, we have the following conditions:
If low < j <= last small then entry[j].key < pivot.
If last small < j < i then entry[j].key >= pivot. */
if (entry[i] < pivot) {
last small = last small + 1;
swap(last small, i); // Move large entry to right and small to left.
}
swap(low, last small); // Put the pivot into its proper position.
return last small;
}
Partitioning the List Data Structures and Program Design In C++
Transp. 28, Sect. 8.8, Quicksort for Contiguous Lists 275 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Analysis of Quicksort
Worst-case analysis:
If the pivot is chosen poorly, one of the partitioned sublists
may be empty and the other reduced by only one entry. In this
case, quicksort is slower than either insertion sort or selection
sort.
Choice of pivot:
First or last entry: Worst case appears for a list already
sorted or in reverse order.
Central entry: Poor cases appear only for unusual orders.
Random entry: Poor cases are very unlikely to occur.
Average-case analysis:
In its average case, quicksort performs
C(n) = 2n ln n + O(n) ≈ 1.39n lg n + O(n)
comparisons of keys in sorting a list of n entries in random
order.
Analysis of Quicksort Data Structures and Program Design In C++
Transp. 29, Sect. 8.8, Quicksort for Contiguous Lists 276 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Mathematical Analysis
Take a list of n distinct keys in random order.
Let C(n) be the average number of comparisons of keys re-
quired to sort the list.
If the pivot is the pth
smallest key, let C(n, p) be the average
number of key comparisons done.
The partition function does n − 1 key comparisons, and the
recursive calls do C(p − 1) and C(n − p) comparisons.
For n ≥ 2, we have C(n, p) = n − 1 + C(p − 1) + C(n − p).
Averaging from p = 1 to p = n gives, for n ≥ 2,
C(n) = n − 1 +
2
n
C(0) + C(1) + · · · + C(n − 1) .
An equation of this form is called a recurrence relation
because it expresses the answer to a problem in terms of
earlier, smaller cases of the same problem.
Write down the same recurrence relation for case n − 1; mul-
tiply the first by n and the second by n − 1; and subtract:
C(n) − 2
n + 1
=
C(n − 1) − 2
n
+
2
n + 1
.
Use the equation over and over to reduce to the case C(1) = 0:
C(n) − 2
n + 1
= −1 + 2
1
n + 1
+
1
n
+
1
n − 1
+ · · · +
1
4
+
1
3
.
Evaluate the harmonic number in the sum: See Appendix A.
Mathematical Analysis Data Structures and Program Design In C++
Transp. 30, Sect. 8.8, Quicksort for Contiguous Lists 277 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Trees, Lists, and Heaps
3
7 8
30292827262524232221201918171615
4
9 10
5
11 12
6
13 14
1 2
0
If the root of the tree is in position 0 of the list, then the left
and right children of the node in position k are in positions
2k + 1 and 2k + 2 of the list, respectively. If these positions
are beyond the end of the list, then these children do not
exist.
DEFINITION A heap is a list in which each entry contains a
key, and, for all positions k in the list, the key at position k
is at least as large as the keys in positions 2k and 2k + 1,
provided these positions exist in the list.
REMARK Many C++ manuals and textbooks refer to the area
used for dynamic memory as the “heap”; this use of the word
“heap” has nothing to do with the present definition.
Heapsort is suitable only for contiguous lists.
Trees, Lists, and Heaps Data Structures and Program Design In C++
Transp. 31, Sect. 8.9, Heaps and Heapsort 278 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
r
y
p
f
y cr p d f b k a
d kb
ca
Heap
a
d
p
kf b
c
fr p d b k a
Promote r Promote f
Insert c
0 1 2 3 4 5 6 7 8
y
a
d
p
kf b
c
fp d b k a y
a
d
f p
kc b
cr p d b k a yr
r
rr
f
0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
p yf k d c b a r
d
f
p
c b a
k
Remove r,
0 1 2 3 4 5 6 7 8
k yf b d c a p r
d
f
k
c a
b
0 1 2 3 4 5 6 7 8
f yd b a c k p r
a
d
f
c
b
0 1 2 3 4 5 6 7 8
d yc b a f k p r
a
c
d
b
a
c
b
0 1 2 3 4 5 6 7 8
a yb c d f k p r
a
a
b
0 1 2 3
c a b d
0 1 2
b a c
Promote p, k,
Reinsert a:
Remove p,
Promote k, b,
Reinsert a:
Remove f,
Promote d,
Reinsert c:
Remove k,
Promote f, d,
Reinsert a:
Remove d,
Promote c,
Reinsert a:
Remove c,
Promote b,
Remove b,
Reinsert a:
Trace of heapsort Data Structures and Program Design In C++
Transp. 32, Sect. 8.9, Heaps and Heapsort 279 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Main function for heapsort:
template <class Record>
void Sortable list<Record> :: heap sort( )
/* Post: The entries of the Sortable list have been rearranged so that their keys
are sorted into nondecreasing order.
Uses: The contiguous List implementation of Chapter 6, build heap, and in-
sert heap. */
{
Record current; // temporary storage for moving entries
int last unsorted; // Entries beyond last unsorted have been sorted.
build heap( ); // First phase: Turn the list into a heap.
for (last unsorted = count − 1; last unsorted > 0;
last unsorted−−) {
current = entry[last unsorted]; // Extract last entry from list.
entry[last unsorted] = entry[0]; // Move top of heap to the end
insert heap(current, 0, last unsorted − 1); // Restore the heap
}
}
Building the initial heap:
template <class Record>
void Sortable list<Record> :: build heap( )
/* Post: The entries of the Sortable list have been rearranged so that it becomes
a heap.
Uses: The contiguous List implementation of Chapter 6, and insert heap. */
{
int low; // All entries beyond the position low form a heap.
for (low = count/2 − 1; low >= 0; low−−) {
Record current = entry[low];
insert heap(current, low, count − 1);
}
}
Heapsort functions Data Structures and Program Design In C++
Transp. 33, Sect. 8.9, Heaps and Heapsort 280 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Insertion into a heap:
template <class Record>
void Sortable list<Record> ::
insert heap(const Record &current, int low, int high)
/* Pre: The entries of the Sortable list between indices low + 1 and high,
inclusive, form a heap. The entry in position low will be discarded.
Post: The entry current has been inserted into the Sortable list and the
entries rearranged so that the entries between indices low and high,
inclusive, form a heap.
Uses: The class Record, and the contiguous List implementation of Chapter 6.
*/
{
int large; // position of child of entry[low] with the larger key
large = 2 * low + 1; // large is now the left child of low.
while (large <= high) {
if (large < high && entry[large] < entry[large + 1])
large++; // large is now the child of low with the largest key.
if (current >= entry[large])
break; // current belongs in position low.
else { // Promote entry[large] and move down the tree.
entry[low] = entry[large];
low = large;
large = 2 * low + 1;
}
}
entry[low] = current;
}
Heap insertion Data Structures and Program Design In C++
Transp. 34, Sect. 8.9, Heaps and Heapsort 281 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Analysis of Heapsort
In its worst case for sorting a list of length n, heapsort per-
forms
2n lg n + O(n)
comparisons of keys, and it performs
n lg n + O(n)
assignments of entries.
Priority Queues
DEFINITION A priority queue consists of entries, such that
each entry contains a key called the priority of the entry. A
priority queue has only two operations other than the usual
creation, clearing, size, full, and empty operations:
Insert an entry.
Remove the entry having the largest (or smallest) key.
If entries have equal keys, then any entry with the largest
key may be removed first.
Heaps and priority queues Data Structures and Program Design In C++
Transp. 35, Sect. 8.9, Heaps and Heapsort 282 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Comparison of Sorting Methods
Use of space
Use of computer time
Programming effort
Statistical analysis
Empirical testing
Comparison of Sorting Methods Data Structures and Program Design In C++
Transp. 36, Sect. 8.10, Review: Comparison of Methods 283 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
Pointers and Pitfalls
1. Many computer systems have a general-purpose sorting util-
ity. If you can access this utility and it proves adequate for
your application, then use it rather than writing a sorting
program from scratch.
2. In choosing a sorting method, take into account the ways in
which the keys will usually be arranged before sorting, the
size of the application, the amount of time available for pro-
gramming, the need to save computer time and space, the
way in which the data structures are implemented, the cost
of moving data, and the cost of comparing keys.
3. Divide-and-conquer is one of the most widely applicable and
most powerful methods for designing algorithms. When faced
with a programming problem, see if its solution can be ob-
tained by first solving the problem for two (or more) problems
of the same general form but of a smaller size. If so, you may
be able to formulate an algorithm that uses the divide-and-
conquer method and program it using recursion.
4. Mergesort, quicksort, and heapsort are powerful sorting meth-
ods, more difficult to program than the simpler methods, but
much more efficient when applied to large lists. Consider the
application carefully to determine whether the extra effort
needed to implement one of these sophisticated algorithms
will be justified.
5. Priority queues are important for many applications. Heaps
provide an excellent implementation of priority queues.
6. Heapsort is like an insurance policy: It is usually slower than
quicksort, but it guarantees that sorting will be completed in
O(n log n) comparisons of keys, as quicksort cannot always
do.
Pointers and Pitfalls Data Structures and Program Design In C++
Transp. 37, Chapter 8, Sorting 284 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458

More Related Content

What's hot

Linked List Static and Dynamic Memory Allocation
Linked List Static and Dynamic Memory AllocationLinked List Static and Dynamic Memory Allocation
Linked List Static and Dynamic Memory Allocation
Prof Ansari
 
Linked list
Linked listLinked list
Linked list
akshat360
 
Stacks & Queues
Stacks & QueuesStacks & Queues
Stacks & Queuestech4us
 
Rana Junaid Rasheed
Rana Junaid RasheedRana Junaid Rasheed
Rana Junaid Rasheed
Rana junaid Rasheed
 
C programming
C programmingC programming
C programming
Karthikeyan A K
 
Stacks,queues,linked-list
Stacks,queues,linked-listStacks,queues,linked-list
Stacks,queues,linked-list
pinakspatel
 
Sorting & Linked Lists
Sorting & Linked ListsSorting & Linked Lists
Sorting & Linked Lists
J.T.A.JONES
 
Stacks & Queues By Ms. Niti Arora
Stacks & Queues By Ms. Niti AroraStacks & Queues By Ms. Niti Arora
Stacks & Queues By Ms. Niti Arora
kulachihansraj
 
Data Structure Lecture 5
Data Structure Lecture 5Data Structure Lecture 5
Data Structure Lecture 5
Teksify
 
Csphtp1 23
Csphtp1 23Csphtp1 23
Csphtp1 23
HUST
 
Array implementation and linked list as datat structure
Array implementation and linked list as datat structureArray implementation and linked list as datat structure
Array implementation and linked list as datat structureTushar Aneyrao
 
Linked list
Linked listLinked list
Linked list
Priyanka Rana
 
Mca ii dfs u-3 linklist,stack,queue
Mca ii dfs u-3 linklist,stack,queueMca ii dfs u-3 linklist,stack,queue
Mca ii dfs u-3 linklist,stack,queue
Rai University
 
DATA STRUCTURES
DATA STRUCTURESDATA STRUCTURES
DATA STRUCTURES
bca2010
 
linked list (c#)
 linked list (c#) linked list (c#)
linked list (c#)
swajahatr
 

What's hot (17)

Linked List Static and Dynamic Memory Allocation
Linked List Static and Dynamic Memory AllocationLinked List Static and Dynamic Memory Allocation
Linked List Static and Dynamic Memory Allocation
 
Linked list
Linked listLinked list
Linked list
 
Stacks & Queues
Stacks & QueuesStacks & Queues
Stacks & Queues
 
Rana Junaid Rasheed
Rana Junaid RasheedRana Junaid Rasheed
Rana Junaid Rasheed
 
Algo>ADT list & linked list
Algo>ADT list & linked listAlgo>ADT list & linked list
Algo>ADT list & linked list
 
C programming
C programmingC programming
C programming
 
Stacks,queues,linked-list
Stacks,queues,linked-listStacks,queues,linked-list
Stacks,queues,linked-list
 
Sorting & Linked Lists
Sorting & Linked ListsSorting & Linked Lists
Sorting & Linked Lists
 
Stacks & Queues By Ms. Niti Arora
Stacks & Queues By Ms. Niti AroraStacks & Queues By Ms. Niti Arora
Stacks & Queues By Ms. Niti Arora
 
Data Structure Lecture 5
Data Structure Lecture 5Data Structure Lecture 5
Data Structure Lecture 5
 
Csphtp1 23
Csphtp1 23Csphtp1 23
Csphtp1 23
 
Array implementation and linked list as datat structure
Array implementation and linked list as datat structureArray implementation and linked list as datat structure
Array implementation and linked list as datat structure
 
Linked list
Linked listLinked list
Linked list
 
Mca ii dfs u-3 linklist,stack,queue
Mca ii dfs u-3 linklist,stack,queueMca ii dfs u-3 linklist,stack,queue
Mca ii dfs u-3 linklist,stack,queue
 
Assignment
AssignmentAssignment
Assignment
 
DATA STRUCTURES
DATA STRUCTURESDATA STRUCTURES
DATA STRUCTURES
 
linked list (c#)
 linked list (c#) linked list (c#)
linked list (c#)
 

Viewers also liked

Shell sort in Data Structure Using C
Shell sort in Data Structure Using CShell sort in Data Structure Using C
Shell sort in Data Structure Using CAshish Gaurkhede
 
3.3 shell sort
3.3 shell sort3.3 shell sort
3.3 shell sort
Krish_ver2
 
Shell sort
Shell sortShell sort
Shell sort
Rajendran
 
Shellsort
ShellsortShellsort
Shellsort
IUPSM
 
Shell sort slide
Shell sort slideShell sort slide
Shell sort slide
Bella Angriani
 
Algorithm & Data Structure - Algoritma Pengurutan
Algorithm & Data Structure - Algoritma PengurutanAlgorithm & Data Structure - Algoritma Pengurutan
Algorithm & Data Structure - Algoritma Pengurutan
Dudy Ali
 
Algorithm: Quick-Sort
Algorithm: Quick-SortAlgorithm: Quick-Sort
Algorithm: Quick-Sort
Tareq Hasan
 
Templates in C++
Templates in C++Templates in C++
Templates in C++Tech_MX
 
Mengintip Kompleksitas
Mengintip KompleksitasMengintip Kompleksitas
Mengintip Kompleksitas
Iwan Pranoto
 
Lecture 07 Data Structures - Basic Sorting
Lecture 07 Data Structures - Basic SortingLecture 07 Data Structures - Basic Sorting
Lecture 07 Data Structures - Basic SortingHaitham El-Ghareeb
 

Viewers also liked (14)

Shell sort in Data Structure Using C
Shell sort in Data Structure Using CShell sort in Data Structure Using C
Shell sort in Data Structure Using C
 
3.3 shell sort
3.3 shell sort3.3 shell sort
3.3 shell sort
 
Shell sort[1]
Shell sort[1]Shell sort[1]
Shell sort[1]
 
Shell sort
Shell sortShell sort
Shell sort
 
Shell sort
Shell sortShell sort
Shell sort
 
Shellsort
ShellsortShellsort
Shellsort
 
Shell sort slide
Shell sort slideShell sort slide
Shell sort slide
 
Algorithm & Data Structure - Algoritma Pengurutan
Algorithm & Data Structure - Algoritma PengurutanAlgorithm & Data Structure - Algoritma Pengurutan
Algorithm & Data Structure - Algoritma Pengurutan
 
Algorithm: Quick-Sort
Algorithm: Quick-SortAlgorithm: Quick-Sort
Algorithm: Quick-Sort
 
Templates in C++
Templates in C++Templates in C++
Templates in C++
 
Mengintip Kompleksitas
Mengintip KompleksitasMengintip Kompleksitas
Mengintip Kompleksitas
 
Merge sort
Merge sortMerge sort
Merge sort
 
Lecture 07 Data Structures - Basic Sorting
Lecture 07 Data Structures - Basic SortingLecture 07 Data Structures - Basic Sorting
Lecture 07 Data Structures - Basic Sorting
 
Quick Sort
Quick SortQuick Sort
Quick Sort
 

Similar to Chapter 8 sorting algo

Unit ii(dsc++)
Unit ii(dsc++)Unit ii(dsc++)
Unit ii(dsc++)
Durga Devi
 
you will implement some sorting algorithms for arrays and linked lis.pdf
you will implement some sorting algorithms for arrays and linked lis.pdfyou will implement some sorting algorithms for arrays and linked lis.pdf
you will implement some sorting algorithms for arrays and linked lis.pdf
clearvisioneyecareno
 
DS UNIT 1.pdf
DS UNIT 1.pdfDS UNIT 1.pdf
DS UNIT 1.pdf
SeethaDinesh
 
DS UNIT 1.pdf
DS UNIT 1.pdfDS UNIT 1.pdf
DS UNIT 1.pdf
SeethaDinesh
 
stacks and queues
stacks and queuesstacks and queues
stacks and queues
DurgaDeviCbit
 
unit 5 stack & queue.ppt
unit 5 stack & queue.pptunit 5 stack & queue.ppt
unit 5 stack & queue.ppt
SeethaDinesh
 
Implement a function called getElements() that takes in two lists. T.pdf
Implement a function called getElements() that takes in two lists. T.pdfImplement a function called getElements() that takes in two lists. T.pdf
Implement a function called getElements() that takes in two lists. T.pdf
arracollection
 
Data structures: linear lists
Data structures: linear listsData structures: linear lists
Data structures: linear lists
ToniyaP1
 
Data Structure
Data Structure Data Structure
Data Structure
Ibrahim MH
 
Data structure
Data  structureData  structure
Data structure
Arvind Kumar
 
Stacks queues-1220971554378778-9
Stacks queues-1220971554378778-9Stacks queues-1220971554378778-9
Stacks queues-1220971554378778-9Getachew Ganfur
 
Python list manipulation basics in detail.pdf
Python list  manipulation basics in detail.pdfPython list  manipulation basics in detail.pdf
Python list manipulation basics in detail.pdf
neonaveen
 
Data Structure
Data StructureData Structure
Data Structure
Karthikeyan A K
 
Linked list
Linked listLinked list
Linked list
KalaivaniKS1
 
Unit - 2.pdf
Unit - 2.pdfUnit - 2.pdf
Unit - 2.pdf
AravindAnand21
 
Data Structure
Data StructureData Structure
Data Structure
HarshGupta663
 
Notes of bca Question paper for exams and tests
Notes of bca Question paper for exams and testsNotes of bca Question paper for exams and tests
Notes of bca Question paper for exams and tests
priyanshukumar97908
 
Lec3-Linked list.pptx
Lec3-Linked list.pptxLec3-Linked list.pptx
Lec3-Linked list.pptx
FaheemMahmood2
 
Ch-8.pdf
Ch-8.pdfCh-8.pdf

Similar to Chapter 8 sorting algo (20)

Unit ii(dsc++)
Unit ii(dsc++)Unit ii(dsc++)
Unit ii(dsc++)
 
you will implement some sorting algorithms for arrays and linked lis.pdf
you will implement some sorting algorithms for arrays and linked lis.pdfyou will implement some sorting algorithms for arrays and linked lis.pdf
you will implement some sorting algorithms for arrays and linked lis.pdf
 
DS UNIT 1.pdf
DS UNIT 1.pdfDS UNIT 1.pdf
DS UNIT 1.pdf
 
DS UNIT 1.pdf
DS UNIT 1.pdfDS UNIT 1.pdf
DS UNIT 1.pdf
 
stacks and queues
stacks and queuesstacks and queues
stacks and queues
 
unit 5 stack & queue.ppt
unit 5 stack & queue.pptunit 5 stack & queue.ppt
unit 5 stack & queue.ppt
 
Implement a function called getElements() that takes in two lists. T.pdf
Implement a function called getElements() that takes in two lists. T.pdfImplement a function called getElements() that takes in two lists. T.pdf
Implement a function called getElements() that takes in two lists. T.pdf
 
Data structures: linear lists
Data structures: linear listsData structures: linear lists
Data structures: linear lists
 
Data Structure
Data Structure Data Structure
Data Structure
 
Data structure
Data  structureData  structure
Data structure
 
Stacks queues-1220971554378778-9
Stacks queues-1220971554378778-9Stacks queues-1220971554378778-9
Stacks queues-1220971554378778-9
 
Python list manipulation basics in detail.pdf
Python list  manipulation basics in detail.pdfPython list  manipulation basics in detail.pdf
Python list manipulation basics in detail.pdf
 
Ds notes
Ds notesDs notes
Ds notes
 
Data Structure
Data StructureData Structure
Data Structure
 
Linked list
Linked listLinked list
Linked list
 
Unit - 2.pdf
Unit - 2.pdfUnit - 2.pdf
Unit - 2.pdf
 
Data Structure
Data StructureData Structure
Data Structure
 
Notes of bca Question paper for exams and tests
Notes of bca Question paper for exams and testsNotes of bca Question paper for exams and tests
Notes of bca Question paper for exams and tests
 
Lec3-Linked list.pptx
Lec3-Linked list.pptxLec3-Linked list.pptx
Lec3-Linked list.pptx
 
Ch-8.pdf
Ch-8.pdfCh-8.pdf
Ch-8.pdf
 

Chapter 8 sorting algo

  • 1. Chapter 8 SORTING 1. Introduction and Notation 2. Insertion Sort 3. Selection Sort 4. Shell Sort 5. Lower Bounds 6. Divide-and-Conquer Sorting 7. Mergesort for Linked Lists 8. Quicksort for Contiguous Lists 9. Heaps and Heapsort 10. Review: Comparison of Methods Outline Data Structures and Program Design In C++ Transp. 1, Chapter 8, Sorting 248 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 2. Requirements In an external sort, there are so many records to be sorted that they must be kept in external files on disks, tapes, or the like. In an internal sort the records can all be kept internally in high-speed memory. We consider only internal sorting. We use the notation and classes set up in Chapters 6 and 7. Thus we shall sort lists of records into the order determined by keys associated with the records. The declarations for a list and the names assigned to various types and operations will be the same as in previous chapters. If two or more of the entries in a list have the same key, we must exercise special care. To analyze sorting algorithms, we consider both the number of comparisons of keys and the number of times entries must be moved inside a list, particularly in a contiguous list. Both the worst-case and the average performance of a sort- ing algorithm are of interest. To find the average, we shall consider what would happen if the algorithm were run on all possible orderings of the list (with n entries, there are n! such orderings altogether) and take the average of the results. Requirements Data Structures and Program Design In C++ Transp. 2, Sect. 8.1, Introduction and Notation 249 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 3. Sortable Lists To write efficient sorting programs, we must access the pri- vate data members of the lists being sorted. Therefore, we shall add sorting functions as methods of our basic List data structures. The augmented list structure forms a new ADT that we shall call a Sortable List, with the following form. template <class Record> class Sortable list: public List<Record> { public: // Add prototypes for sorting methods here. private: // Add prototypes for auxiliary functions here. }; Hence a Sortable list is a List with extra sorting methods. The base list class can be any of the List implementations of Chapter 6. We use a template parameter class called Record to stand for entries of the Sortable list. Every Record has an associated key of type Key. A Record can be implicitly converted to the corresponding Key. The keys (hence also the records) can be compared under the operations ‘ < ,’ ‘ > ,’ ‘ >= ,’ ‘ <= ,’ ‘ == ,’ and ‘ != .’ Any of the Record implementations discussed in Chapter 7 can be supplied, by a client, as the template parameter of a Sortable list. Sortable Lists Data Structures and Program Design In C++ Transp. 3, Sect. 8.1, Introduction and Notation 250 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 4. Ordered Insertion An ordered list is an abstract data type, defined as a list in which each entry has a key, and such that the keys are in order; that is, if entry i comes before entry j in the list, then the key of entry i is less than or equal to the key of entry j . For ordered lists, we shall often use two new operations that have no counterparts for other lists, since they use keys rather than positions to locate the entry. One operation retrieves an entry with a specified key from the ordered list. Retrieval by key from an ordered list is exactly the same as searching. The second operation, ordered insertion, inserts a new entry into an ordered list by using the key in the new entry to determine where in the list to insert it. Note that ordered insertion is not uniquely specified if the list already contains an entry with the same key as the new entry, since the new entry could go into more than one position. New entry Ordered list Move last entry Move previous entry Complete insertion cat cow dog pig ram cat cow dog pig ram cat cow dog pig ram cat cow dog hen pig ram hen (a) (b) (c) (d) Ordered Insertion Data Structures and Program Design In C++ Transp. 4, Sect. 8.2, Insertion Sort 251 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 5. Insertion Sort Example: cat cow dog ewe hen ram Initial order Insert second entry Insert third entry Insert fourth entry Insert fifth entry Insert sixth entry sorted hen cow cat ram ewe dog cat cow hen ram ewe dog cat cow hen ram ewe dog cat cow ewe hen ram dog cow hen cat ram ewe dog sorted . . . . . . . sorted unsorted . . . . . . Main step, contiguous case: UnsortedSorted ≤ current > current Remove current; shift entries right Before: Sorted current UnsortedSorted Sorted Unsorted ≤ current Reinsert current; > current Insertion Sort Data Structures and Program Design In C++ Transp. 5, Sect. 8.2, Insertion Sort 252 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 6. Contiguous Insertion Sort template <class Record> void Sortable list<Record> :: insertion sort( ) /* Post: The entries of the Sortable list have been rearranged so that the keys in all the entries are sorted into nondecreasing order. Uses: Methods for the class Record; the contiguous List implementation of Chapter 6 */ { int first unsorted; // position of first unsorted entry int position; // searches sorted part of list Record current; // holds the entry temporarily removed from list for (first unsorted = 1; first unsorted < count; first unsorted++) if (entry[first unsorted] < entry[first unsorted − 1]) { position = first unsorted; current = entry[first unsorted]; // Pull unsorted entry out of the list. do { // Shift all entries until the proper position is found. entry[position] = entry[position − 1]; position−−; // position is empty. } while (position > 0 && entry[position − 1] > current); entry[position] = current; } } Contiguous Insertion Sort Data Structures and Program Design In C++ Transp. 6, Sect. 8.2, Insertion Sort 253 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 7. Linked Insertion Sort With no movement of data, there is no need to search from the end of the sorted sublist, as for the contiguous case. Traverse the original list, taking one entry at a time and in- serting it in the proper position in the sorted list. Pointer last sorted references the end of the sorted part of the list. Pointer first unsorted == last sorted->next references the first entry that has not yet been inserted into the sorted sublist. Pointer current searches the sorted part of the list to find where to insert *first unsorted. If *first unsorted belongs before the head of the list, then insert it there. Otherwise, move current down the list until first unsorted->entry <= current->entry and then insert *first unsorted before *current. To enable inser- tion before *current, keep a second pointer trailing in lock step one position closer to the head than current. A sentinel is an extra entry added to one end of a list to ensure that a loop will terminate without having to include a separate check. Since last sorted->next == first unsorted, the node *first unsorted is already in position to serve as a sentinel for the search, and the loop moving current is simplified. A list with 0 or 1 entry is already sorted, so by checking these cases separately we avoid trivialities elsewhere. Linked Insertion Sort Data Structures and Program Design In C++ Transp. 7, Sect. 8.2, Insertion Sort 254 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 8. template <class Record> void Sortable list<Record> :: insertion sort( ) /* Post: The entries of the Sortable list have been rearranged so that the keys in all the entries are sorted into nondecreasing order. Uses: Methods for the class Record, linked List implementation of Chapter 6. */ { Node <Record> *first unsorted, // the first unsorted node to be inserted *last sorted, // tail of the sorted sublist *current, // used to traverse the sorted sublist *trailing; // one position behind current if (head != NULL) { // Otherwise, the empty list is already sorted. last sorted = head; // The first node alone makes a sorted sublist. while (last sorted->next != NULL) { first unsorted = last sorted->next; if (first unsorted->entry < head->entry) { // Insert *first unsorted at the head of the sorted list: last sorted->next = first unsorted->next; first unsorted->next = head; head = first unsorted; } else { // Search the sorted sublist to insert *first unsorted: trailing = head; current = trailing->next; while (first unsorted->entry > current->entry) { trailing = current; current = trailing->next; } // *first unsorted now belongs between *trailing and *current. if (first unsorted == current) last sorted = first unsorted; // already in right position else { last sorted->next = first unsorted->next; first unsorted->next = current; trailing->next = first unsorted; } } } } } Linked insertion sort Data Structures and Program Design In C++ Transp. 8, Sect. 8.2, Insertion Sort 255 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 9. last_sorted first_unsorted last_sorted Case 1: Case 2: head Partially sorted: *first_unsorted belongs at head of list *first_unsorted belongs between *trailing and *current head first_unsorted head trailing current last_sorted first_unsorted TraceoflinkedinsertionsortDataStructuresandProgramDesignInC++ Transp.9,Sect.8.2,InsertionSort256©1999Prentice-Hall,Inc.,UpperSaddleRiver,N.J.07458
  • 10. Analysis of Insertion Sort The average number of comparisons for insertion sort applied to a list of n items in random order is 1 4 n2 + O(n). The average number of assignments of items for insertion sort applied to a list of n items in random order is also 1 4 n2 +O(n). The best case for contiguous insertion sort occurs when the list is already in order, when insertion sort does nothing except n − 1 comparisons of keys. The worst case for contiguous insertion sort occurs when the list is in reverse order. THEOREM 8.1. Verifying that a list of n entries is in the correct order requires at least n − 1 comparisons of keys. Insertion sort verifies that a list is correctly sorted as quickly as any method can. Analysis of Insertion Sort Data Structures and Program Design In C++ Transp. 10, Sect. 8.2, Insertion Sort 257 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 11. Selection Sort Example: Initial order Colored box denotes largest unsorted key. Gray boxes denote other unsorted keys. Sorted hen cow cat dog ewe ram ewe cow cat dog hen ram dog cow cat ewe hen ram cat cow dog ewe hen ram cat cow dog ewe hen ram hen cow cat ram ewe dog General step: Unsorted small keys Sorted, large keys Maximum unsorted key Swap Current position Unsorted small keys Sorted, large keys Selection Sort Data Structures and Program Design In C++ Transp. 11, Sect. 8.3, Selection Sort 258 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 12. Selection sort: template <class Record> void Sortable list<Record> :: selection sort( ) /* Post: The entries of the Sortable list have been rearranged so that the keys in all the entries are sorted into nondecreasing order. Uses: max key, swap. */ { for (int position = count − 1; position > 0; position−−) { int max = max key(0, position); swap(max, position); } } Find maximum key: template <class Record> int Sortable list<Record> :: max key(int low, int high) /* Pre: low and high are valid positions in the Sortable list and low <= high. Post: The position of the entry between low and high with the largest key is returned. Uses: The class Record. The contiguous List implementation of Chapter 6. */ { int largest, current; largest = low; for (current = low + 1; current <= high; current++) if (entry[largest] < entry[current]) largest = current; return largest; } Code for contiguous selection sort Data Structures and Program Design In C++ Transp. 12, Sect. 8.3, Selection Sort 259 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 13. Swap entries: template <class Record> void Sortable list<Record> :: swap(int low, int high) /* Pre: low and high are valid positions in the Sortable list. Post: The entry at position low is swapped with the entry at position high. Uses: The contiguous List implementation of Chapter 6. */ { Record temp; temp = entry[low]; entry[low] = entry[high]; entry[high] = temp; } Analysis and comparison: Selection Insertion (average) Assignments of entries 3.0n + O(1) 0.25n2 + O(n) Comparisons of keys 0.5n2 + O(n) 0.25n2 + O(n) Selection sort Data Structures and Program Design In C++ Transp. 13, Sect. 8.3, Selection Sort 260 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 14. Example of Shell Sort Unsorted Tim Dot Eva Roy Tom Kim Guy Amy Jon Ann Jim Kay Ron Jan Sublists incr. 5 Sublists incr. 3 3-Sorted Dot Eva Tim Roy Tom Recombined Jim Dot Amy Jan Ann Kim Guy Eva Jon Tom Tim Kay Ron Roy List incr. 1 Guy Ann Amy Jan Dot Jon Jim Eva Kay Ron Roy Kim Tom Tim Sorted Amy Ann Dot Eva Guy Jan Jim Jon Kay Kim Ron Roy Tim Tom 5-Sorted Dot Amy Jim Jan Ann Guy Amy Kim Jon Ann Kay Ron Jim Jan Guy Eva Kim Jon Tom Kay Ron Tim Roy Jim Dot Amy Jan Ann Kim Guy Eva Jon Tom Tim Kay Ron Roy Guy Ann Amy Jan Dot Jon Jim Eva Kay Ron Roy Kim Tom Tim Example of Shell Sort Data Structures and Program Design In C++ Transp. 14, Sect. 8.4, Shell Sort 261 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 15. Shell Sort template <class Record> void Sortable list<Record> :: shell sort( ) /* Post: The entries of the Sortable list have been rearranged so that the keys in all the entries are sorted into nondecreasing order. Uses: sort interval */ { int increment, // spacing of entries in sublist start; // starting point of sublist increment = count; do { increment = increment/3 + 1; for (start = 0; start < increment; start++) sort interval(start, increment); // modified insertion sort } while (increment > 1); } Shell Sort Data Structures and Program Design In C++ Transp. 15, Sect. 8.4, Shell Sort 262 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 16. Lower Bounds for Sorting How fast is it possible to sort? Insertion sort Selection sort F F F T T T a ≤ b b ≤ c a ≤ b ≤ c a ≤ c b < a ≤ c c < b < a c < a ≤ b a ≤ c < b a < ba < c b < c c < b a < b a < c b ≤ c ≤ a c < b ≤ a b ≤ c < a b ≤ a < c impossible a < c ≤ b a < b < cimpossiblec ≤ a < b F FT T F T F T a < b F F F T T T F T F T a ≤ cb ≤ c THEOREM 8.2 Any algorithm that sorts a list of n entries by use of key comparisons must, in its worst case, perform at least lg n! comparisons of keys, and, in the average case, it must perform at least lg n! comparisons of keys. Lower Bounds for Sorting Data Structures and Program Design In C++ Transp. 16, Sect. 8.5, Lower Bounds 263 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 17. Divide and Conquer Sorting Outline: void Sortable list :: sort( ) { if the list has length greater than 1 { partition the list into lowlist, highlist; lowlist.sort( ); highlist.sort( ); combine(lowlist, highlist); } } Mergesort: We chop the list into two sublists of sizes as nearly equal as possible and then sort them separately. Afterward, we care- fully merge the two sorted sublists into a single sorted list. Quicksort: We first choose some key from the list for which, we hope, about half the keys will come before and half after. Call this key the pivot. Then we partition the items so that all those with keys less than the pivot come in one sublist, and all those with greater keys come in another. Then we sort the two reduced lists separately, put the sublists together, and the whole list will be in order. Divide and Conquer Sorting Data Structures and Program Design In C++ Transp. 17, Sect. 8.6, Divide-and-Conquer Sorting 264 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 18. Start Finish 26 33 35 29 19 12 26 33 35 29 191219352926 33 12 26 33 35 29 26 29 33 35 19 12 22 12 19 22 22 29 19 12 22353326 26 29 33 35221912 Recursiontree,mergesortof7numbersDataStructuresandProgramDesignInC++ Transp.18,Sect.8.6,Divide-and-ConquerSorting265©1999Prentice-Hall,Inc.,UpperSaddleRiver,N.J.07458
  • 19. Quicksort of 7 Numbers Sort (26, 33, 35, 29, 12, 22) Partition into (19, 12, 22) and (33, 35, 29); pivot = 26 Sort (19, 12, 22) Sort (33, 35, 29) Combine into (12, 19, 22, 26, 29, 33 35) Partition into (12) and (22); pivot = 19 Sort (12) Sort (22) Combine into (12, 19, 22) Partition into (29) and (35); pivot = 33 Sort (29) Sort (35) Combine into (29, 33, 35) 26 19 33 12 22 29 35 Trace and recursion tree, quicksort of 7 numbers Data Structures and Program Design In C++ Transp. 19, Sect. 8.6, Divide-and-Conquer Sorting 266 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 20. Tim TomDot Amy Eva Ann Roy Kim Guy Ron Jon Jim Kay Jan Tim Tom Dot Amy Eva Ann Roy Kim Guy Ron Jon Jim Kay Jan Pivot is central key. Pivot is first key. Recursiontrees,quicksortof14namesDataStructuresandProgramDesignInC++ Transp.20,Sect.8.6,Divide-and-ConquerSorting267©1999Prentice-Hall,Inc.,UpperSaddleRiver,N.J.07458
  • 21. Mergesort for Linked Lists Interface method: template <class Record> void Sortable list<Record> :: merge sort( ) /* Post: The entries of the sortable list have been rearranged so that their keys are sorted into nondecreasing order. Uses: Linked List implementation of Chapter 6 and recursive merge sort. */ { recursive merge sort(head); } Recursive function: template <class Record> void Sortable list<Record> :: recursive merge sort(Node<Record> * &sub list) /* Post: The nodes referenced by sub list have been rearranged so that their keys are sorted into nondecreasing order. The pointer parameter sub list is reset to point at the node containing the smallest key. Uses: The linked List implementation of Chapter 6; the functions divide from, merge, and recursive merge sort. */ { if (sub list != NULL && sub list->next != NULL) { Node<Record> *second half = divide from(sub list); recursive merge sort(sub list); recursive merge sort(second half); sub list = merge(sub list, second half); } } Mergesort for Linked Lists Data Structures and Program Design In C++ Transp. 21, Sect. 8.7, Mergesort for Linked Lists 268 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 22. Divide Linked List in Half template <class Record> Node<Record> *Sortable list<Record> :: divide from(Node<Record> *sub list) /* Post: The list of nodes referenced by sub list has been reduced to its first half, and a pointer to the first node in the second half of the sublist is returned. If the sublist has an odd number of entries, then its first half will be one entry larger than its second. Uses: The linked List implementation of Chapter 6. */ { Node<Record> *position, // traverses the entire list *midpoint, // moves at half speed of position to midpoint *second half; if ((midpoint = sub list) == NULL) return NULL; // List is empty. position = midpoint->next; while (position != NULL) { // Move position twice for midpoint’s one move. position = position->next; if (position != NULL) { midpoint = midpoint->next; position = position->next; } } second half = midpoint->next; midpoint->next = NULL; return second half; } Divide Linked List in Half Data Structures and Program Design In C++ Transp. 22, Sect. 8.7, Mergesort for Linked Lists 269 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 23. Initial situation: first 4 8 9 second 5 7 After merging: 4 8 9 5 7 3 1 3 1? Dummy node combined MergingtwosortedlinkedlistsDataStructuresandProgramDesignInC++ Transp.23,Sect.8.7,MergesortforLinkedLists270©1999Prentice-Hall,Inc.,UpperSaddleRiver,N.J.07458
  • 24. Merge Function template <class Record> Node<Record> *Sortable list<Record> :: merge(Node<Record> *first, Node<Record> *second) /* Pre: first and second point to ordered lists of nodes. Post: A pointer to an ordered list of nodes is returned. The ordered list contains all entries that were referenced by first and second. The original lists of nodes referenced by first and second are no longer available. Uses: Methods for Record class; the linked List implementation of Chapter 6. */ { Node<Record> *last sorted; // points to the last node of sorted list Node<Record> combined; // dummy first node, points to merged list last sorted = &combined; while (first != NULL && second != NULL) { // Attach node with smaller key if (first->entry <= second->entry) { last sorted->next = first; last sorted = first; first = first->next; // Advance to the next unmerged node. } else { last sorted->next = second; last sorted = second; second = second->next; } } // After one list ends, attach the remainder of the other. if (first == NULL) last sorted->next = second; else last sorted->next = first; return combined.next; } Merge Function Data Structures and Program Design In C++ Transp. 24, Sect. 8.7, Mergesort for Linked Lists 271 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 25. Analysis of Mergesort 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 = n 22222 2 2 2 4 4 4 4 88 16 Lower bound: lg n! ≈ n lg n − 1.44n + O(log n) Mergesort: n lg n − 1.1583n + 1, Insertion sort: 1 4 n2 + O(n) Analysis of Mergesort Data Structures and Program Design In C++ Transp. 25, Sect. 8.7, Mergesort for Linked Lists 272 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 26. Quicksort for Contiguous Lists Interface method: template <class Record> void Sortable list<Record> :: quick sort( ) /* Post: The entries of the Sortable list have been rearranged so that their keys are sorted into nondecreasing order. Uses: Contiguous List implementation of Chapter 6, recursive quick sort. */ { recursive quick sort(0, count − 1); } Recursive function: template <class Record> void Sortable list<Record> :: recursive quick sort(int low, int high) /* Pre: low and high are valid positions in the Sortable list. Post: The entries of the Sortable list have been rearranged so that their keys are sorted into nondecreasing order. Uses: Contiguous List implementation of Chapter 6, recursive quick sort, and partition. */ { int pivot position; if (low < high) { // Otherwise, no sorting is needed. pivot position = partition(low, high); recursive quick sort(low, pivot position − 1); recursive quick sort(pivot position + 1, high); } } Quicksort for Contiguous Lists Data Structures and Program Design In C++ Transp. 26, Sect. 8.8, Quicksort for Contiguous Lists 273 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 27. Goal (postcondition): low < pivot pivot ≥ pivot pivot_position high Loop invariant: low last_small i < pivotpivot ≥ pivot ? Restore the invariant: swap last_small i < pivotpivot ≥ pivot ?< pivot last_small i < pivotpivot ≥ pivot ? Final position: low < pivotpivot ≥ pivot last_small high Partitioning the list: Algorithm development Data Structures and Program Design In C++ Transp. 27, Sect. 8.8, Quicksort for Contiguous Lists 274 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 28. Partitioning the List template <class Record> int Sortable list<Record> :: partition(int low, int high) /* Pre: low and high are valid positions of the Sortable list, with low <= high. Post: The center (or left center) entry in the range between indices low and high of the Sortable list has been chosen as a pivot. All entries of the Sortable list between indices low and high, inclusive, have been rearranged so that those with keys less than the pivot come before the pivot and the remaining entries come after the pivot. The final position of the pivot is returned. Uses: swap(int i, int j) (interchanges entries in positions i and j of a Sortable list), the contiguous List implementation of Chapter 6, and methods for the class Record. */ { Record pivot; int i, // used to scan through the list last small; // position of the last key less than pivot swap(low, (low + high)/2); pivot = entry[low]; // First entry is now pivot. last small = low; for (i = low + 1; i <= high; i++) /* At the beginning of each iteration of this loop, we have the following conditions: If low < j <= last small then entry[j].key < pivot. If last small < j < i then entry[j].key >= pivot. */ if (entry[i] < pivot) { last small = last small + 1; swap(last small, i); // Move large entry to right and small to left. } swap(low, last small); // Put the pivot into its proper position. return last small; } Partitioning the List Data Structures and Program Design In C++ Transp. 28, Sect. 8.8, Quicksort for Contiguous Lists 275 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 29. Analysis of Quicksort Worst-case analysis: If the pivot is chosen poorly, one of the partitioned sublists may be empty and the other reduced by only one entry. In this case, quicksort is slower than either insertion sort or selection sort. Choice of pivot: First or last entry: Worst case appears for a list already sorted or in reverse order. Central entry: Poor cases appear only for unusual orders. Random entry: Poor cases are very unlikely to occur. Average-case analysis: In its average case, quicksort performs C(n) = 2n ln n + O(n) ≈ 1.39n lg n + O(n) comparisons of keys in sorting a list of n entries in random order. Analysis of Quicksort Data Structures and Program Design In C++ Transp. 29, Sect. 8.8, Quicksort for Contiguous Lists 276 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 30. Mathematical Analysis Take a list of n distinct keys in random order. Let C(n) be the average number of comparisons of keys re- quired to sort the list. If the pivot is the pth smallest key, let C(n, p) be the average number of key comparisons done. The partition function does n − 1 key comparisons, and the recursive calls do C(p − 1) and C(n − p) comparisons. For n ≥ 2, we have C(n, p) = n − 1 + C(p − 1) + C(n − p). Averaging from p = 1 to p = n gives, for n ≥ 2, C(n) = n − 1 + 2 n C(0) + C(1) + · · · + C(n − 1) . An equation of this form is called a recurrence relation because it expresses the answer to a problem in terms of earlier, smaller cases of the same problem. Write down the same recurrence relation for case n − 1; mul- tiply the first by n and the second by n − 1; and subtract: C(n) − 2 n + 1 = C(n − 1) − 2 n + 2 n + 1 . Use the equation over and over to reduce to the case C(1) = 0: C(n) − 2 n + 1 = −1 + 2 1 n + 1 + 1 n + 1 n − 1 + · · · + 1 4 + 1 3 . Evaluate the harmonic number in the sum: See Appendix A. Mathematical Analysis Data Structures and Program Design In C++ Transp. 30, Sect. 8.8, Quicksort for Contiguous Lists 277 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 31. Trees, Lists, and Heaps 3 7 8 30292827262524232221201918171615 4 9 10 5 11 12 6 13 14 1 2 0 If the root of the tree is in position 0 of the list, then the left and right children of the node in position k are in positions 2k + 1 and 2k + 2 of the list, respectively. If these positions are beyond the end of the list, then these children do not exist. DEFINITION A heap is a list in which each entry contains a key, and, for all positions k in the list, the key at position k is at least as large as the keys in positions 2k and 2k + 1, provided these positions exist in the list. REMARK Many C++ manuals and textbooks refer to the area used for dynamic memory as the “heap”; this use of the word “heap” has nothing to do with the present definition. Heapsort is suitable only for contiguous lists. Trees, Lists, and Heaps Data Structures and Program Design In C++ Transp. 31, Sect. 8.9, Heaps and Heapsort 278 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 32. r y p f y cr p d f b k a d kb ca Heap a d p kf b c fr p d b k a Promote r Promote f Insert c 0 1 2 3 4 5 6 7 8 y a d p kf b c fp d b k a y a d f p kc b cr p d b k a yr r rr f 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 p yf k d c b a r d f p c b a k Remove r, 0 1 2 3 4 5 6 7 8 k yf b d c a p r d f k c a b 0 1 2 3 4 5 6 7 8 f yd b a c k p r a d f c b 0 1 2 3 4 5 6 7 8 d yc b a f k p r a c d b a c b 0 1 2 3 4 5 6 7 8 a yb c d f k p r a a b 0 1 2 3 c a b d 0 1 2 b a c Promote p, k, Reinsert a: Remove p, Promote k, b, Reinsert a: Remove f, Promote d, Reinsert c: Remove k, Promote f, d, Reinsert a: Remove d, Promote c, Reinsert a: Remove c, Promote b, Remove b, Reinsert a: Trace of heapsort Data Structures and Program Design In C++ Transp. 32, Sect. 8.9, Heaps and Heapsort 279 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 33. Main function for heapsort: template <class Record> void Sortable list<Record> :: heap sort( ) /* Post: The entries of the Sortable list have been rearranged so that their keys are sorted into nondecreasing order. Uses: The contiguous List implementation of Chapter 6, build heap, and in- sert heap. */ { Record current; // temporary storage for moving entries int last unsorted; // Entries beyond last unsorted have been sorted. build heap( ); // First phase: Turn the list into a heap. for (last unsorted = count − 1; last unsorted > 0; last unsorted−−) { current = entry[last unsorted]; // Extract last entry from list. entry[last unsorted] = entry[0]; // Move top of heap to the end insert heap(current, 0, last unsorted − 1); // Restore the heap } } Building the initial heap: template <class Record> void Sortable list<Record> :: build heap( ) /* Post: The entries of the Sortable list have been rearranged so that it becomes a heap. Uses: The contiguous List implementation of Chapter 6, and insert heap. */ { int low; // All entries beyond the position low form a heap. for (low = count/2 − 1; low >= 0; low−−) { Record current = entry[low]; insert heap(current, low, count − 1); } } Heapsort functions Data Structures and Program Design In C++ Transp. 33, Sect. 8.9, Heaps and Heapsort 280 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 34. Insertion into a heap: template <class Record> void Sortable list<Record> :: insert heap(const Record &current, int low, int high) /* Pre: The entries of the Sortable list between indices low + 1 and high, inclusive, form a heap. The entry in position low will be discarded. Post: The entry current has been inserted into the Sortable list and the entries rearranged so that the entries between indices low and high, inclusive, form a heap. Uses: The class Record, and the contiguous List implementation of Chapter 6. */ { int large; // position of child of entry[low] with the larger key large = 2 * low + 1; // large is now the left child of low. while (large <= high) { if (large < high && entry[large] < entry[large + 1]) large++; // large is now the child of low with the largest key. if (current >= entry[large]) break; // current belongs in position low. else { // Promote entry[large] and move down the tree. entry[low] = entry[large]; low = large; large = 2 * low + 1; } } entry[low] = current; } Heap insertion Data Structures and Program Design In C++ Transp. 34, Sect. 8.9, Heaps and Heapsort 281 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 35. Analysis of Heapsort In its worst case for sorting a list of length n, heapsort per- forms 2n lg n + O(n) comparisons of keys, and it performs n lg n + O(n) assignments of entries. Priority Queues DEFINITION A priority queue consists of entries, such that each entry contains a key called the priority of the entry. A priority queue has only two operations other than the usual creation, clearing, size, full, and empty operations: Insert an entry. Remove the entry having the largest (or smallest) key. If entries have equal keys, then any entry with the largest key may be removed first. Heaps and priority queues Data Structures and Program Design In C++ Transp. 35, Sect. 8.9, Heaps and Heapsort 282 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 36. Comparison of Sorting Methods Use of space Use of computer time Programming effort Statistical analysis Empirical testing Comparison of Sorting Methods Data Structures and Program Design In C++ Transp. 36, Sect. 8.10, Review: Comparison of Methods 283 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458
  • 37. Pointers and Pitfalls 1. Many computer systems have a general-purpose sorting util- ity. If you can access this utility and it proves adequate for your application, then use it rather than writing a sorting program from scratch. 2. In choosing a sorting method, take into account the ways in which the keys will usually be arranged before sorting, the size of the application, the amount of time available for pro- gramming, the need to save computer time and space, the way in which the data structures are implemented, the cost of moving data, and the cost of comparing keys. 3. Divide-and-conquer is one of the most widely applicable and most powerful methods for designing algorithms. When faced with a programming problem, see if its solution can be ob- tained by first solving the problem for two (or more) problems of the same general form but of a smaller size. If so, you may be able to formulate an algorithm that uses the divide-and- conquer method and program it using recursion. 4. Mergesort, quicksort, and heapsort are powerful sorting meth- ods, more difficult to program than the simpler methods, but much more efficient when applied to large lists. Consider the application carefully to determine whether the extra effort needed to implement one of these sophisticated algorithms will be justified. 5. Priority queues are important for many applications. Heaps provide an excellent implementation of priority queues. 6. Heapsort is like an insurance policy: It is usually slower than quicksort, but it guarantees that sorting will be completed in O(n log n) comparisons of keys, as quicksort cannot always do. Pointers and Pitfalls Data Structures and Program Design In C++ Transp. 37, Chapter 8, Sorting 284 © 1999 Prentice-Hall, Inc., Upper Saddle River, N.J. 07458