Searching and Sorting
Linear Search
In a linear search we search an array for an element by starting at the
first element in the array and traversing till we find the element.
File: search1.cpp
#include <iostream>
using namespace std;
//Will return the index of the element if found
//else will return -1 .
int searchList(const int list[], int numElems, int value)
{
int index = 0; // Used as a subscript to search array
int position = -1; // To record position of search value
bool found = false; // Flag to indicate if the value was found
while (index < numElems && !found)
{
if (list[index] == value) // If the value is found
{
found = true; // Set the flag
position = index; // Record the value's subscript
}
index++; // Go to the next element
}
return position; // Return the position, or -1
}
int main()
{
int arr1[] = { 2, 5, 3, 7, 1 } ;
cout << searchList( arr1 , 5 , 3 ) << endl ;
cout << searchList( arr1 , 5 , 8 ) << endl ;
}
If we have an array of 10 elements and we can assume that each element has
the same likelihood to be searched then the number of average comparisons
needed by our algorithm is:
Total sum of comparisions = ( n * (n+1) ) / 2 )
Divide by n to get average = ( n + 1 ) / 2
1 for position 0
2 for position 1
.
.
10 for position 9
The average number of comparisons is 1+2 +3 ..+ 10 = 55 /10 = 5.5 .
This makes sense since 5 is about the middle of the array.
Binary Search
Binary search assumes that the elements are sorted to begin with.
Ex:
1 2 4 5 7
Let's assume our array contains the above.
Let's assume our array contains the above and we are
looking for the number 1. Our pseudo code starts like this.
LeftIndex = 0
RightIndex = 4
We take the middle
middle = LeftIndex + RightIndex / 2
and compare the number with 1. 4 is not equal to 1.
That tells us if the number 1 did exist then it must be
to the left of the number 4 since the array is sorted.
So now our RightIndex becomes 2-1 which is 1 .
middle = LeftIndex + RightIndex / 2
middle = 0 + 1 / 2 = 0
Now we compare middle value of 1 with the value that we are searching for
and that value is 1 so we are done. We keep narrowing our subsection of the
array till our value is either found or not found.
Since we cut the array by 2 every time we only need log n worst case
searches where the base is 2.
File: search2.cpp
#include <iostream>
using namespace std;
//Will return the index of the element if found
//else will return -1 .
int binarySearch(const int arr1[], int numElems, int value)
{
int leftIndex = 0 ;
int rightIndex = numElems - 1 ;
int result = -1 ;
int middleIndex = 0 ;
while( leftIndex <= rightIndex )
{
middleIndex = ( leftIndex + rightIndex ) / 2 ;
if ( arr1[middleIndex] == value )
return middleIndex ;
else if ( arr1[middleIndex] < value )
{
leftIndex = middleIndex + 1 ;
}
else
{
rightIndex = middleIndex - 1 ;
}
} //while
return result ;
}
int main()
{
int arr1[] = { 1, 2, 3, 5, 7 } ;
cout << binarySearch( arr1 , 5 , 3 ) << endl ;
cout << binarySearch( arr1 , 5 , 8 ) << endl ;
}
Bubble Sort
In bubble sort the array is traversed from left to
right and the maximum element is placed to the right.
Ex:
4 3 2 1
3 4 2 1
3 2 4 1
3 2 1 4
//The element 4 is exchanged with the right element
and bubbles to the right.
2 3 1 4
2 1 3 4
//Now 3 has been placed to the right
1 2 3 4
//Now 2 is placed to the right and we have a sorted array.
File: sort1.cpp
#include <iostream>
using namespace std ;
void showArray(const int array[], int size)
{
for (int count = 0; count < size; count++)
cout << array[count] << " ";
cout << endl;
}
void sortArray(int array[], int size)
{
bool swap;
int temp;
do
{
swap = false;
for (int count = 0; count < (size - 1); count++)
{
if (array[count] > array[count + 1])
{ //swap operation
temp = array[count];
array[count] = array[count + 1];
array[count + 1] = temp;
swap = true;
}
} //for
} while (swap);
}
int main()
{
int arr1[] = { 5 , 4 , 3 , 2 , 1 } ;
sortArray( arr1, 5 ) ;
showArray( arr1 , 5 ) ;
return ( 0 ) ;
}
The while loop runs till "swap" is false. That means the array is sorted
at this stage. The line:
count < (size - 1)
runs a loop from the first element to one element before the last. However
after the first element bubbles all the way to the right we do not really need
to check up to the last position. We can just check up to the last greatest
element that bubbled to the right.
File: sort2.cpp
#include <iostream>
using namespace std ;
void showArray(const int array[], int size)
{
for (int count = 0; count < size; count++)
cout << array[count] << " ";
cout << endl;
}
void sortArray(int array[], int size)
{
bool swap;
int temp;
do
{
swap = false;
int limit = size - 1 ;
for (int count = 0; count < limit; count++ )
{
if (array[count] > array[count + 1])
{ //swap operation
temp = array[count];
array[count] = array[count + 1];
array[count + 1] = temp;
swap = true;
}
} //for
limit-- ;
showArray( array , 5 ) ;
} while (swap);
}
int main()
{
int arr1[] = { 5 , 4 , 3 , 2 , 1 } ;
showArray( arr1 , 5 ) ;
sortArray( arr1, 5 ) ;
showArray( arr1 , 5 ) ;
return ( 0 ) ;
}
$ g++ sort2.cpp ; ./a.exe
5 4 3 2 1
4 3 2 1 5
3 2 1 4 5
2 1 3 4 5
1 2 3 4 5
1 2 3 4 5
Selection Sort
In selection sort the array is traversed from left to
right and the minimum element is placed in the first position.
Then we start from the second element and find the minimum
in the right section and place it in the second element.
It is similar to bubble sort but swapping is not done as
we traverse the array.
Ex:
4 3 2 1
0 1 2 3
Start from the index 0. The minimum
element is 1 so swap it with 4.
1 3 2 4
Start at position 1 and the minimum element is 2 so
swap it with the element 3 at position 1 .
1 2 3 4
Start at position 2; the minimum element is 3 so we don't
do anything. Now we can stop because the last element
has to be the largest at this stage.
File: sort3.cpp
#include <iostream>
using namespace std ;
//Selection Sort
void showArray(const int array[], int size)
{
for (int count = 0; count < size; count++)
cout << array[count] << " ";
cout << endl;
}
void selectionSort(int array[], int size)
{
int startScan, minIndex, minValue;
for (startScan = 0; startScan < (size - 1); startScan++)
{
minIndex = startScan;
minValue = array[startScan];
for(int index = startScan + 1; index < size; index++)
{
if (array[index] < minValue)
{
minValue = array[index];
minIndex = index;
}
}
array[minIndex] = array[startScan];
array[startScan] = minValue;
showArray( array , 5 ) ;
}
}
int main()
{
int arr1[] = { 5 , 4 , 3 , 2 , 1 } ;
showArray( arr1 , 5 ) ;
selectionSort( arr1, 5 ) ;
showArray( arr1 , 5 ) ;
return ( 0 ) ;
}
$ g++ sort3.cpp ; ./a.exe
5 4 3 2 1
1 4 3 2 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
Insertion Sort
Insertion sort is like arranging the cards in a card game.
We start with the second card and place it in the right
place on the left. Now our leftmost 2 cards are sorted so
we start with the 3rd card and place it in the right
position.
Ex:
4 3 2 1
Start with 3
3 4 2 1
Now we work on 2
swapping it with the left element till we find
a position for it.
3 2 4 1
2 3 4 1
Finally we work on 1.
2 3 1 4
2 1 3 4
1 2 3 4
File: sort4.cpp
#include <iostream>
using namespace std ;
//Selection Sort
void showArray(const int array[], int size)
{
for (int count = 0; count < size; count++)
cout << array[count] << " ";
cout << endl;
}
void insertionSort(int array[], int size)
{
int startScan, minIndex, minValue;
for (int i1 = 1; i1 < size ; i1++)
{
for( int j1=i1 ; j1 > 0 ; j1-- )
{
if( array[j1] < array[j1-1] )
{
int temp = array[j1];
array[j1] = array[j1-1];
array[j1-1] = temp;
}
} //for
showArray( array , 5 ) ;
} //for
}
int main()
{
int arr1[] = { 5 , 4 , 3 , 2 , 1 } ;
showArray( arr1 , 5 ) ;
insertionSort( arr1, 5 ) ;
showArray( arr1 , 5 ) ;
return ( 0 ) ;
}
$ g++ sort4.cpp ; ./a.exe
5 4 3 2 1
4 5 3 2 1
3 4 5 2 1
2 3 4 5 1
1 2 3 4 5
1 2 3 4 5
We can be a little bit more efficient by not swapping and just
"shifting" the value and then only place the current value when
we have found the right position.
File: sort5.cpp
#include <iostream>
using namespace std ;
//Selection Sort
void showArray(const int array[], int size)
{
for (int count = 0; count < size; count++)
cout << array[count] << " ";
cout << endl;
}
void insertionSort(int array[], int size)
{
int startScan, minIndex, minValue;
for (int i1 = 1; i1 < size ; i1++)
{
int currentValue = array[i1] ;
int j1=0 ;
for( j1=i1 ; j1 > 0 ; j1-- )
{
if( currentValue < array[j1-1] )
{
//shift
array[j1] = array[j1-1];
}
else
{ //found the right position
break ;
}
} //for
array[j1] = currentValue ;
showArray( array , size ) ;
} //for
}
int main()
{
int arr1[] = { 4 , 3 , 2 , 1 } ;
showArray( arr1 , 4 ) ;
insertionSort( arr1, 4 ) ;
showArray( arr1 , 4 ) ;
return ( 0 ) ;
}
$ g++ sort5.cpp ; ./a.exe
4 3 2 1
3 4 2 1
2 3 4 1
1 2 3 4
1 2 3 4
Exercises
1) An array contains the following values:
6 , 1 , 4, 3
Show how the values change for bubble sort, selection sort
and insertion sort in the array.
2) Change the bubble sort algorith to sort in descending order
instead of ascending.