You are on page 1of 20

20

Searching and
Sorting
With sobs and tears
he sorted out
Those of the largest size
Lewis Carroll

Attempt the end, and never


stand to doubt;
Nothings so hard, but search
will nd it out.
Robert Herrick

Tis in my memory lockd,


And you yourself shall keep
the key of it.
William Shakespeare

OBJECTIVES
In this chapter you will learn:

To search for a given value in a vector using binary


search.
To sort a vector using the recursive merge sort algorithm.
To determine the efciency of searching and sorting
algorithms.

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.

Chapter 20 Searching and Sorting

Self-Review Exercises
20.1

Fill in the blanks in each of the following statements:


a) A selection sort application would take approximately
times as long to run
on a 128-element vector as on a 32-element vector.
ANS: 16, because an O(n2) algorithm takes 16 times as long to sort four times as much information.
b) The efficiency of merge sort is
.
ANS: O(n log n).

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

// Exercise 20.5 Solution: Ex20_05.cpp


// This program sorts a vector's values into ascending order.
#include <iostream>
using std::cout;
using std::endl;

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.

Chapter 20 Searching and Sorting

Data items in original order


2
6
4
8 10 12 89 68
Data items in ascending order
2
4
6
8 10 12 37 45

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

// Exercise 20.6 Part A Solution: Ex20_06.cpp


#include <iostream>
using std::cout;
using std::endl;
#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;
int numberOfComp = 0; // number of comparisons made
int comp; // used to control for loop and for subscripts
// display original, unsorted vector
cout << "Data items in original order\n";
for ( int i = 0; i < SIZE; i++ )
cout << setw( 4 ) << a[ i ];
cout << "\n\n";
// begin sorting the vector
for ( int pass = 1; pass < SIZE; pass++ )
{

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

Data items in original order


2
6
4
8 10 12 89
After
After
After
After
After
After
After
After
After

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

Data items in ascending order


2
4
6
8 10 12 37 45
Number of comparisons = 45

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.

Chapter 20 Searching and Sorting


b) The data in the vector may already be in the proper order or near-proper order, so why
make nine passes (of a 10-element vector) if fewer will suffice? Modify the sort to check
at the end of each pass whether any swaps have been made. If none have been made, the
data must already be in the proper order, so the program should terminate. If swaps
have been made, at least one more pass is needed.
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
38
39
40
41
42
43
44
45
46

// Exercise 20.6 Part B Solution: Ex20_06.cpp


#include <iostream>
using std::cout;
using std::endl;
#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;
int numberOfComp = 0; // number of comparisons made
int comp; // used to control for loop and for subscripts
bool swapCheck = true; // was a swap made
// display original, unsorted vector
cout << "Data items in original order\n";
for ( int i = 0; i < SIZE; i++ )
cout << setw( 4 ) << a[ i ];
cout << "\n\n";
// begin sorting the vector
for ( int pass = 1; pass < SIZE && swapCheck; pass++ )
{
cout << "After pass " << pass - 1 << ": ";
swapCheck = false; // assume no swaps will be made
// traverse and compare unsorted part of vector
for ( comp = 0; comp < SIZE - pass; comp++ )
{
numberOfComp++;

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

// compare adjacent vector elements


if ( a[ comp ] > a[ comp + 1 ] )
{
hold = a[ comp ];
a[ comp ] = a[ comp + 1 ];
a[ comp + 1 ] = hold;
swapCheck = true; // a swap has been made
} // 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

Data items in original order


2
6
4
8 10 12 89

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

Data items in ascending order


2
4
6
8 10 12 37 45
Number of comparisons = 30

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.

Chapter 20 Searching and Sorting


order of the values in the one-dimensional vector is 100, 3 and 97. On the third (hundreds digit) pass, 100 is placed in row 1, 3 is placed in row 0 and 97 is placed in row 0
(after the 3). After this last gathering pass, the original vector is in sorted order.
Note that the two-dimensional vector of buckets is 10 times the length of the integer vector being sorted. This sorting technique provides better performance than a
bubble sort, but requires much more memorythe bubble sort requires space for only
one additional element of data. This comparison is an example of the spacetime
trade-off: The bucket sort uses more memory than the bubble sort, but performs better. This version of the bucket sort requires copying all the data back to the original
vector on each pass. Another possibility is to create a second two-dimensional bucket
vector and repeatedly swap the data between the two bucket vectors.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// Exercise 20.7 Solution: BucketSort.h


// Class BucketSort contains a vector of random integers and a function
// that uses bucket sort to sort the integers.
#include <vector>
using std::vector;

1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Exercise 20.7 Solution: BucketSort.cpp


// BucketSort class member-function definitions.
#include <iostream>
using std::cout;
using std::endl;

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

#include <cstdlib> // prototypes for functions srand and rand


using std::rand;
using std::srand;
#include <ctime> // prototype for function time
using std::time;
#include "BucketSort.h" // BucketSort class definition

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

Chapter 20 Searching and Sorting

for ( int k = 0; k < size; ++k )


{
// bucketNumber example for hundreds digit:
// (1234 % 1000 - 1234 % 100) / 100 --> 2
bucketNumber = ( data[ k ] % divisor - data[ k ] %
( divisor / 10 ) ) / ( divisor / 10 );
// retrieve value in bucket[bucketNumber][0] to determine
// which element of the row to store a[i] in.
elementNumber = ++bucket[ bucketNumber ][ 0 ];
bucket[ bucketNumber ][ elementNumber ] = data[ k ];
} // end for
} // end function distributeElements
// return elements to original array
void BucketSort::collectElements()
{
int subscript = 0;
// retrieve elements from bucket vector
for ( int i = 0; i < 10; i++ )
{
for ( int j = 1; j <= bucket[ i ][ 0 ]; j++ )
data[ subscript++ ] = bucket[ i ][ j ];
} // end for
} // end function collectElements
// determine the number of digits in the largest number
int BucketSort::numberOfDigits()
{
int largest = data[ 0 ];
int digits = 0;
// find largest vector element
for ( int i = 1; i < size; i++ )
{
if ( data[ i ] > largest )
largest = data[ i ];
} // end for
// find number of digits of largest element
while ( largest != 0 )
{
digits++;
largest /= 10;
} // end while
return digits;
} // end function numberOfDigits
// set all buckets to zero
void BucketSort::zeroBucket()
{

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

// Exercise 20.7 Solution: Ex20_07.cpp


// Test program that demonstrates bucket sort.
#include <iostream>
using std::cout;
using std::endl;
#include "BucketSort.h" // BucketSort class definition
int main()
{
BucketSort sortVector( 12 ); // create BucketSort object
cout << "Vector elements in original order:\n";
sortVector.displayElements();
sortVector.sort(); // sort the vector
cout << "\nVector elements in sorted order:\n";
sortVector.displayElements();
return 0;
} // end main

Vector elements in original order:


88 84 80 96 15 30 76 51 88 52 11 71
Vector elements in sorted order:
11 15 30 51 52 71 76 80 84 88 88 96

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

// Exercise 20.8 Solution: Ex20_08.cpp


// Searching a vector with recursive linear search.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <vector>

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

Chapter 20 Searching and Sorting

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

Enter the integer search key: 14


Found value in element 7

Enter the integer search key: 15


Value not found

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
20.9

(Recursive Binary Search) Modify Fig. 20.3 to use recursive function

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

// Exercise 20.9 Solution: BinarySearch.h


// Class that contains a vector of random integers and a recursive
// binary search function that finds an integer.
#include <vector>
using std::vector;

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

// Exercise 20.9 Solution: BinarySearch.cpp


// BinarySearch class member-function definition.
#include <iostream>
using std::cout;
using std::endl;

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

#include <cstdlib> // prototypes for functions srand and rand


using std::rand;
using std::srand;
#include <ctime> // prototype for function time
using std::time;
#include <algorithm> // prototype for sort function
#include "BinarySearch.h" // class BinarySearch definition
// constructor initializes vector with random ints and sorts the vector
BinarySearch::BinarySearch( 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

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

Chapter 20 Searching and Sorting

std::sort( data.begin(), data.end() ); // sort the data


} // end BinarySearch constructor
// perform a binary search on the data
int BinarySearch::binarySearch( int searchElement ) const
{
int low = 0; // low end of the search area
int high = size - 1; // high end of the search area
return recursiveBinarySearch( searchElement, low, high );
} // end function binarySearch
// perform a recursive binary search on the data
int BinarySearch::recursiveBinarySearch(
int searchElement, int low, int high ) const
{
if ( low > high ) // test base case; no element left to check
return -1;
// print remaining elements of vector to be searched
displaySubElements( low, high );
int middle = ( low + high + 1 ) / 2; // middle element
// output spaces for alignment
for ( int i = 0; i < middle; i++ )
cout << "
";
cout << " * " << endl; // indicate current middle
int location = -1; // variable to return; -1 if the value was not found
// if the element is found at the middle
if ( searchElement == data[ middle ] )
location = middle; // location is the current middle
else if ( searchElement < data[ middle ] ) // middle is too high
// eliminate the higher half
location = recursiveBinarySearch( searchElement, low, middle - 1 );
else // middle element is too low
// eliminate the lower half
location = recursiveBinarySearch( searchElement, middle + 1, high );
return location; // return location of search key
} // end function recursiveBinarySearch
// display values in vector
void BinarySearch::displayElements() const
{
displaySubElements( 0, size - 1 );
} // end function displayElements
// display certain values in vector
void BinarySearch::displaySubElements( int low, int high ) const

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

// Exercise 20.9 Solution: Ex20_09.cpp


// BinarySearch test program.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

15

for ( int i = 0; i < low; i++ ) // output spaces for alignment


cout << "
";
for ( int i = low; i <= high; i++ ) // output elements left in vector
cout << data[ i ] << " ";

cout << endl;


} // end function displaySubElements

#include "BinarySearch.h" // class BinarySearch definition


int main()
{
int searchInt; // search key
int position; // location of search key in vector
// create vector and output it
BinarySearch searchVector( 15 );
searchVector.displayElements();
// get input from user
cout << "\nPlease enter an integer value (-1 to quit): ";
cin >> searchInt; // read an int from user
cout << endl;
// repeatedly input an integer; -1 terminates the program
while ( searchInt != -1 )
{
// use binary search to try to find integer
position = searchVector.binarySearch( searchInt );
// return value of -1 indicates integer was not found
if ( position == -1 )
cout << "The integer " << searchInt << " was not found.\n";
else
cout << "The integer " << searchInt
<< " was found in position " << position << ".\n";
// get input from user
cout << "\n\nPlease enter an integer value (-1 to quit): ";
cin >> searchInt; // read an int from user
cout << endl;
} // end while

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

16
43
44

Chapter 20 Searching and Sorting

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

// Exercise 20.10 Solution: Ex20_10.cpp


// Quick sort of a vector.
#include <iostream>
using std::cout;
using std::endl;

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

Chapter 20 Searching and Sorting

#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

Chapter 20 Searching and Sorting

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

The sorted vector values are:


4
4
8 14 23 38 52 66

89

97

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

You might also like