chapter 8: sorting. contents algorithms for sorting list (both for contiguous lists and linked...
TRANSCRIPT
Contents
• Algorithms for Sorting List(both for contiguous lists and linked lists)
– Insertion Sort– Selection Sort– Bubble / Quick Sort– Merge Sort– Heap Sort
• Analysis of Sorting Algorithms
Introduction Internal Sorting (*)
All records to be sorted are kept in memory.
Performance of Sorting Algorithms Consider both the number of comparisons of ke
ys and the number of times entries must be moved inside a list.
Both the worst-case and the average performance of a sorting algorithm are of interest.
Records and Keys 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 ‘ ! = ’ .
template <class Record>void Sortable list<Record> :: insertion_sort( ) {
int first_unsorted; //position of first unsorted entryint position; //searches sorted part of listRecord current; //holds the entry temporarily removed from listfor (first_unsorted = 1; first_unsorted < count; first_unsorted++)
if (entry[first_unsorted] < entry[first_unsorted - 1]) {position = first_unsorted;current = entry[first_unsorted]; do { //move entry[position] = entry[position - 1];
position--; } while (position > 0 && entry[position - 1] > current);entry[position] = current; //insert
}}
Contiguous Insertion Sorting
Motivation
• Major disadvantage of insertion sort– Even after most entries have been sorted prop
erly into the first part of the list , the insertion of a later entry may require that many of them be moved.
– 移动数据• Selection sorting method solves it.
Contiguous Implementation of Selection Sort
template <class Record> void Sortable list<Record> :: selection_sort( ) {
for (int position = count - 1; position > 0; position--) {int max = max_key(0, position);swap(max, position);
}}
Contiguous Implementation of Selection Sort (cont’)
template <class Record>int Sortable list<Record> :: max_key(int low, int high){
int largest, current;largest = low;for (current = low + 1; current <= high; current++)if (entry[largest] < entry[current])
largest = current;return largest;
}
template <class Record>void Sortable list<Record> :: swap(int low, int high) {
Record temp;temp = entry[low];entry[low] = entry[high];entry[high] = temp;
}
Analysis of Selection Sort
Less move operations
Selection sort is suitable for both contiguous list and linked list.
Bubble Sorting
void BubbleSort(List &L ){ for (i = 1; i < L.count; ++i ) //count –1 pass for (j = 0; j < L.count – i; ++j) if (L.entry[j] > L.entry[j+1]){ //swap data = L.entry[j]; L.r[j] = L.r[j+1];
L.r[j+1] = data; } }
O(n2)
Motivation
• It is much easier to sort short lists than long ones.
• Divide and conquer: dividing a problem into smaller but similar sub-problems.
• Thus, Divide-and-Conquer Sorting divides the list into two sub-lists and sort them separately.
Outline of Divide-and-Conquer Sorting
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);
}}
Quicksort Steps of Quicksort
1. First choose a key named pivot, about half the keys will come before it and half after. The simplest rule is to choose the first number in a list as the pivot.
2. Partition the items so that all those with keys less than the pivot come in one sub-list, and all those with greater keys come in another.
3. Sort the two sub-lists separately
4. Put the sub-lists together.
Trace and Recursion tree, Quicksort of 7 numbers
Pivot is the first key
Sort (26, 33, 35, 29, 19, 12, 22)
Quicksort for Contiguous Lists
template <class Record>void Sortable_list<Record> :: quick_sort( ) { recursive_quick_sort(0, count - 1);}
template <class Record>void Sortable_list<Record> :: recursive_quick_sort(int low, int high) { int pivot_position; if (low < high) { pivot_position = partition(low, high); // …. recursive_quick_sort(low, pivot_ position - 1); recursive_quick_sort(pivot_position + 1, high); }}
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.
• Middle of three — first, last, central entry
template <class Record>void Sortable_list<Record> ::int Partition(int low, int high){
Record pivot;int i, Last_small; //position of the last key less than pivotswap(low, (low + high)/2); //interchanges entries in two positionspivot = entry[low]; // First entry is now pivotLast_small = low;for (i = low + 1; i <= high; i++)
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;
}
Partition with Central Entry Pivot
{26, 33, 35, 29, 19, 12, 22}, pivot = 29
{29, 33, 35, 26, 19, 12, 22}, i = 3, last_small=1, {29, 26, 35, 33, 19, 12, 22}, i = 4, last_small=2,{29, 26, 19, 33, 35, 12, 22}, i = 5, last_small=3,{29, 26, 19, 12, 35, 33, 22}, i = 6, last_small=4,{29, 26, 19, 12, 22, 33, 35}, low=0, last_small=4,{22, 26, 19, 12, 29, 33, 35}
Tracking of Partition
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.
• Average-case analysis:
• Quicksort is suitable only for contiguous list.
Summary of Sorting Methods• Use of space
– Most sorting methods use little extra space
– Quick need some space for tracing recursion execution.
• Use of computer time– Insertion and selection sort is O(n2)
– quick sort is fastest, O(nlogn) //average case
• Programming effort– Simple sorting methods for small list
– Sophisticated sorting methods for large list