Professional Documents
Culture Documents
Searching and
Sorting
With sobs and tears
he sorted out
Those of the largest size
Lewis Carroll
OBJECTIVES
In this chapter you will learn:
It is an immutable law in
business that words are
words, explanations are
explanations, promises are
promises but only
performance is reality.
Harold S. Green
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Self-Review Exercises
20.1
20.2 What key aspect of both the binary search and the merge sort accounts for the logarithmic
portion of their respective Big Os?
ANS: Both of these algorithms incorporate halvingsomehow reducing something by
half. The binary search eliminates from consideration one-half of the vector after each
comparison. The merge sort splits the vector in half each time it is called.
20.3 In what sense is the insertion sort superior to the merge sort? In what sense is the merge sort
superior to the insertion sort?
ANS: The insertion sort is easier to understand and to implement than the merge sort. The
merge sort is far more efficient (O(n log n)) than the insertion sort (O(n2)).
20.4 In the text, we say that after the merge sort splits the vector into two subvectors, it then sorts
these two subvectors and merges them. Why might someone be puzzled by our statement that it
then sorts these two subvectors?
ANS: In a sense, it does not really sort these two subvectors. It simply keeps splitting the
original vector in half until it provides a one-element subvector, which is, of course,
sorted. It then builds up the original two subvectors by merging these one-element
vectors to form larger subvectors, which are then merged, and so on.
Exercises
[Note: Most of the exercises shown here are duplicates of exercises from Chapters 78. We include
the exercises again here as a convenience for readers studying searching and sorting in this chapter.]
20.5 (Bubble Sort) Implement bubble sortanother simple yet inefficient sorting technique. It
is called bubble sort or sinking sort because smaller values gradually bubble their way to the top
of the vector (i.e., toward the first element) like air bubbles rising in water, while the larger values
sink to the bottom (end) of the vector. The technique uses nested loops to make several passes
through the vector. Each pass compares successive pairs of elements. If a pair is in increasing order
(or the values are equal), the bubble sort leaves the values as they are. If a pair is in decreasing order,
the bubble sort swaps their values in the vector.
The rst pass compares the rst two elements of the vector and swaps them if necessary. It
then compares the second and third elements in the vector. The end of this pass compares the last
two elements in the vector and swaps them if necessary. After one pass, the largest element will be
in the last index. After two passes, the largest two elements will be in the last two indices. Explain
why bubble sort is an O(n2) algorithm.
ANS:
1
2
3
4
5
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iomanip>
using std::setw;
#include <vector>
using std::vector;
int main()
{
const int SIZE = 10;
int data[ SIZE ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };
vector < int > a; // declare vector< int > to sort
// fill the vector with values
for ( int i = 0; i < SIZE; i++ )
a.push_back( data[ i ] );
int hold; // temporary location used to swap vector elements
cout << "Data items in original order\n";
// output original vector
for ( int i = 0; i < SIZE; i++ )
cout << setw( 4 ) << a[ i ];
// bubble sort
// loop to control number of passes
for ( int pass = 0; pass < SIZE - 1; pass++ )
{
// loop to control number of comparisons per pass
for ( int j = 0; j < SIZE - 1; j++ )
{
// compare side-by-side elements and swap them if
// first element is greater than second element
if ( a[ j ] > a[ j + 1 ] )
{
hold = a[ j ];
a[ j ] = a[ j + 1 ];
a[ j + 1 ] = hold;
} // end if
} // end for
} // end for
cout << "\nData items in ascending order\n";
// output sorted vector
for ( int k = 0; k < SIZE; k++ )
cout << setw( 4 ) << a[ k ];
cout << endl;
return 0;
} // end main
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
45
37
68
89
20.6 (Enhanced Bubble Sort) Make the following simple modifications to improve the performance of the bubble sort you developed in Exercise 20.5:
a) After the first pass, the largest number is guaranteed to be in the highest-numbered element of the vector; after the second pass, the two highest numbers are in place; and
so on. Instead of making nine comparisons (for a 10-element vector) on every pass,
modify the bubble sort to make only the eight necessary comparisons on the second
pass, seven on the third pass, and so on.
ANS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
cout << "After pass " << pass - 1 << ": ";
// traverse and compare unsorted part of vector
for ( comp = 0; comp < SIZE - pass; comp++ )
{
numberOfComp++;
// compare adjacent vector elements
if ( a[ comp ] > a[ comp + 1 ] )
{
hold = a[ comp ];
a[ comp ] = a[ comp + 1 ];
a[ comp + 1 ] = hold;
} // end if
cout << setw( 3 ) << a[ comp ];
} // end inner for
cout << setw( 3 ) << a[ comp ] << '\n'; // print last vector value
} // end outer for
// diplay vector in sorted order
cout << "\nData items in ascending order\n";
for ( int j = 0; j < SIZE; j++ )
cout << setw( 4 ) << a[ j ];
// display the number of comparisons made
cout << "\nNumber of comparisons = " << numberOfComp << endl;
return 0;
} // end main
pass
pass
pass
pass
pass
pass
pass
pass
pass
0:
1:
2:
3:
4:
5:
6:
7:
8:
2
2
2
2
2
2
2
2
2
4
4
4
4
4
4
4
4
4
6
6
6
6
6
6
6
6
8
8
8
8
8
8
8
10
10
10
10
10
10
68
12
12
12
12
12
45
37
68 45 37 89
45 37 68
37 45
37
68
89
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
68
After
After
After
After
12
12
12
12
pass
pass
pass
pass
0:
1:
2:
3:
2
2
2
2
4
4
4
4
6
6
6
6
8
8
8
8
10
10
10
10
45
37
68 45 37 89
45 37 68
37 45
37
68
89
20.7 (Bucket Sort) A bucket sort begins with a one-dimensional vector of positive integers to be
sorted and a two-dimensional vector of integers with rows indexed from 0 to 9 and columns indexed
from 0 to n 1, where n is the number of values to be sorted. Each row of the two-dimensional
vector is referred to as a bucket. Write a class named BucketSort containing a function called sort
that operates as follows:
a) Place each value of the one-dimensional vector into a row of the bucket vector, based
on the values ones (rightmost) digit. For example, 97 is placed in row 7, 3 is placed
in row 3 and 100 is placed in row 0. This procedure is called a distribution pass.
b) Loop through the bucket vector row by row, and copy the values back to the original
vector. This procedure is called a gathering pass. The new order of the preceding values
in the one-dimensional vector is 100, 3 and 97.
c) Repeat this process for each subsequent digit position (tens, hundreds, thousands, etc.).
On the second (tens digit) pass, 100 is placed in row 0, 3 is placed in row 0
(because 3 has no tens digit) and 97 is placed in row 9. After the gathering pass, the
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class BucketSort
{
public:
BucketSort( int ); // constructor initializes vector
void displayElements() const; // display vector elements
void sort(); // perform a bucket sort on vector
private:
int size; // vector size
vector< int > data; // vector of ints
vector< vector < int > > bucket; // two-dimensional vector of ints
// utility functions used by member function bucketSort
void distributeElements( int );
void collectElements();
int numberOfDigits();
void zeroBucket();
}; // end class BucketSort
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// constructor
BucketSort::BucketSort( int vectorSize )
{
size = ( vectorSize > 0 ? vectorSize : 10 ); // validate vectorSize
srand( time( 0 ) ); // seed using current time
// fill vector with random ints in range 10-99
for ( int i = 0; i < size; i++ )
data.push_back( 10 + rand() % 90 ); // 10-99
// create bucket vector of appropriate size
for ( int i = 0; i < 10; i++ )
bucket.push_back( vector < int >( size ) );
} // end BucketSort constructor
// display vector elements
void BucketSort::displayElements() const
{
for ( int i = 0; i < size; i++ )
cout << data[ i ] << " ";
cout << endl;
} // end function displayElements
// perform a bucket sort on vector
void BucketSort::sort()
{
int totalDigits;
zeroBucket();
totalDigits = numberOfDigits();
// put elements in buckets for sorting
// once sorted, get elements from buckets
for ( int i = 1; i <= totalDigits; i++ )
{
distributeElements( i );
collectElements();
if ( i != totalDigits )
zeroBucket(); // set all bucket contents to zero
} // end for
} // end function sort
// distribute elements into buckets based on specified digit
void BucketSort::distributeElements( int digit )
{
int divisor = 10;
int bucketNumber;
int elementNumber;
for ( int i = 1; i < digit; ++i ) // determine the divisor
divisor *= 10; // used to get specific digit
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
10
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
11
123
// set all vector elements to zero
124
for ( int i = 0; i < 10; i++ )
125
{
126
for ( int j = 0; j < size; j++ )
127
bucket[ i ][ j ] = 0;
128
} // end for
129 } // end function zeroBucket
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
20.8
(Recursive Linear Search) Modify Exercise 7.33 to use recursive function recursiveLinto perform a linear search of the vector. The function should receive the search key and
starting index as arguments. If the search key is found, return its index in the vector; otherwise, return 1. Each call to the recursive function should check one index in the vector.
earSearch
ANS:
1
2
3
4
5
6
7
8
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
12
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using std::vector;
int recursiveLinearSearch( vector < int > &, int, int, int );
int main()
{
const int SIZE = 100;
vector < int > data( SIZE );
int searchKey;
int element;
// initialize vector elements
for ( int loop = 0; loop < SIZE; loop++ )
data[ loop ] = 2 * loop;
// obtain search key from user
cout << "Enter the integer search key: ";
cin >> searchKey;
// search array for search key
element = recursiveLinearSearch( data, searchKey, 0, SIZE - 1 );
// display if search key was found
if ( element != -1 )
cout << "Found value in element " << element << endl;
else
cout << "Value not found" << endl;
return 0; // indicates successful termination
} // end main
// function to search vector for specified key
int recursiveLinearSearch(
vector < int > &array, int key, int low, int high )
{
// search array for key
if ( array[ low ] == key )
return low;
else if ( low == high )
return -1;
else
return recursiveLinearSearch( array, key, low + 1, high );
} // end function recursiveLinearSearch
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
20.9
13
recursiveBinary-
Search to perform a binary search of the vector. The function should receive the search key, starting
index and ending index as arguments. If the search key is found, return its index in the vector. If the
search key is not found, return 1.
ANS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class BinarySearch
{
public:
BinarySearch( int ); // constructor initializes vector
int binarySearch( int ) const; // perform binary search on the vector
void displayElements() const; // display vector elements
private:
int size; // vector size
vector< int > data; // vector of ints
void displaySubElements( int, int ) const; // display range of values
// perform recursive binary search on the vector
int recursiveBinarySearch( int, int, int ) const;
}; // end class BinarySearch
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
14
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
80
81
82
83
84
85
86
87
88
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
15
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
16
43
44
return 0;
} // end main
12 16 26 35 40 42 45 47 49 58 66 83 88 91 97
Please enter an integer value (-1 to quit): 46
12 16 26 35 40 42 45 47 49 58 66 83 88 91 97
*
12 16 26 35 40 42 45
*
40 42 45
*
45
*
The integer 46 was not found.
Please enter an integer value (-1 to quit): 66
12 16 26 35 40 42 45 47 49 58 66 83 88 91 97
*
49 58 66 83 88 91 97
*
49 58 66
*
66
*
The integer 66 was found in position 10.
Please enter an integer value (-1 to quit): 100
12 16 26 35 40 42 45 47 49 58 66 83 88 91 97
*
49 58 66 83 88 91 97
*
88 91 97
*
97
*
The integer 100 was not found.
Please enter an integer value (-1 to quit): -1
20.10 (Quicksort) The recursive sorting technique called quicksort uses the following basic algorithm for a one-dimensional vector of values:
a) Partitioning Step: Take the first element of the unsorted vector and determine its final
location in the sorted vector (i.e., all values to the left of the element in the vector are
less than the element, and all values to the right of the element in the vector are greater
than the elementwe show how to do this below). We now have one element in its
proper location and two unsorted subvectors.
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
17
b) Recursion Step: Perform Step 1 on each unsorted subvector. Each time Step 1 is performed on a subvector, another element is placed in its final location of the sorted vector, and two unsorted subvectors are created. When a subvector consists of one element,
that element is in its final location (because a one-element vector is already sorted).
The basic algorithm seems simple enough, but how do we determine the nal position of the rst element of each subvector? As an example, consider the following set of
values (the element in bold is the partitioning elementit will be placed in its nal
location in the sorted vector):
37 2 6 4 89 8 10 12 68 45
Starting from the rightmost element of the vector, compare each element with 37 until
an element less than 37 is found; then swap 37 and that element. The rst element less
than 37 is 12, so 37 and 12 are swapped. The new vector is
12 2 6 4 89 8 10 37 68 45
Element 12 is in italics to indicate that it was just swapped with 37.
Starting from the left of the vector, but beginning with the element after 12, compare each element with 37 until an element greater than 37 is foundthen swap 37
and that element. The rst element greater than 37 is 89, so 37 and 89 are swapped.
The new vector is
12 2 6 4 37 8 10 89 68 45
Starting from the right, but beginning with the element before 89, compare each element with 37 until an element less than 37 is foundthen swap 37 and that element.
The rst element less than 37 is 10, so 37 and 10 are swapped. The new vector is
12 2 6 4 10 8 37 89 68 45
Starting from the left, but beginning with the element after 10, compare each element
with 37 until an element greater than 37 is foundthen swap 37 and that element.
There are no more elements greater than 37, so when we compare 37 with itself, we
know that 37 has been placed in its nal location of the sorted vector. Every value to
the left of 37 is smaller than it, and every value to the right of 37 is larger than it.
Once the partition has been applied on the previous vector, there are two unsorted
subvectors. The subvector with values less than 37 contains 12, 2, 6, 4, 10 and 8. The
subvector with values greater than 37 contains 89, 68 and 45. The sort continues
recursively, with both subvectors being partitioned in the same manner as the original
vector.
Based on the preceding discussion, write recursive function quickSortHelper to
sort a one-dimensional integer vector. The function should receive as arguments a
starting index and an ending index on the original vector being sorted.
ANS:
1
2
3
4
5
6
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
18
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iomanip>
using std::setw;
#include <cstdlib>
using std::rand;
using std::srand;
#include <ctime>
using std::time;
#include <vector>
using std::vector;
// function prototypes
void quickSortHelper( vector < int > &, int, int );
int partition( vector < int > &, int, int );
void swap( int * const, int * const );
int main()
{
const int MAX_NUMBER = 100;
const int SIZE = 10;
vector < int > vectorToBeSorted( SIZE );
int loop;
srand( time( 0 ) );
// randomly generate content
for ( loop = 0; loop < SIZE; loop++ )
vectorToBeSorted[ loop ] = rand() % MAX_NUMBER;
cout << "Initial vector values are:\n";
// print out values of the vector
for ( loop = 0; loop < SIZE; loop++ )
cout << setw( 4 ) << vectorToBeSorted[ loop ];
cout << "\n\n";
// if there is only one element
if ( SIZE == 1 )
cout << "Vector is sorted: " << vectorToBeSorted[ 0 ] << '\n';
else
{
quickSortHelper( vectorToBeSorted, 0, SIZE - 1 );
cout << "The sorted vector values are:\n";
for ( loop = 0; loop < SIZE; loop++ )
cout << setw( 4 ) << vectorToBeSorted[ loop ];
cout << endl;
} // end else
return 0;
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
19
} // end main
// recursive function to sort vector
void quickSortHelper( vector < int > &data, int first, int last )
{
int currentLocation;
if ( first >= last )
return;
currentLocation = partition( data, first, last ); // place an element
quickSortHelper( data, first, currentLocation - 1 ); // sort left side
quickSortHelper( data, currentLocation + 1, last ); // sort right side
} // end function quickSortHelper
// partition the vector into multiple sections
int partition( vector < int > &data, int left, int right )
{
int position = left;
// loop through the portion of the vector
while ( true )
{
while ( data[ position ] <= data[ right ] && position != right )
right--;
if ( position == right )
return position;
if ( data[ position ] > data[ right ])
{
swap( &data[ position ], &data[ right ] );
position = right;
} // end if
while ( data[ left ] <= data[ position ] && left != position )
left++;
if ( position == left )
return position;
if ( data[ left ] > data[ position ] )
{
swap( &data[ position ], &data[ left ] );
position = left;
} // end if
} // end while
} // end function partition
// swap locations
void swap( int * const ptr1, int * const ptr2 )
{
int temp;
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
20
115
temp = *ptr1;
116
*ptr1 = *ptr2;
117
*ptr2 = temp;
118 } // end function swap
Initial vector values are:
14
8 97
4 89 52 66
38
23
89
97
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.