Lab 3 – Searching and Sorting
Part 1 – Sorting
1.1 – Bubble Sort
1.1.1 – Pseudocode
swapped = 1 while swapped swapped = 0 for i from 0 to size - 1 if arr[i > arr[i + 1] swap( a[i], a[i + 1] ) swapped = 1
1.1.2 – Time Complexity
Bubble sort being the least efficient sorting algorithm covered in this lab has a worst case of O(n^2).
1.2 – Selection Sort
1.2.1 – Pseudocode
for (i = size-1; i > 0; --i) { Set integer index to 0 as the index of the largest element Set integer largest to arr[index] for (j = 1; j <= i; j++) { if (arr[j] > largest) Change largest to arr[j] and index to j } swap(arr[i], arr[index]) }
1.2.2 – Time Complexity
Selection sort is also a quadratic algorithm with a worst case of O(n^2).
1.3 – Insertion Sort
1.3.1 – Pseudocode
Set int value i to first+1, where first is the first index of your array while i < size Set integer tmp to arr[i] Set int value j to i-1 while j >= 0 and arr[j] > tmp Set arr[j+1] equal to arr[j] Decrement j end while Set arr[j+1] equal to tmp Increment i end while
Part 2 – Searching
2.1 – Serial Search
2.1.1 – Pseudocode
// Searches for a desired element in an array of n elements starting from a[first] // where first is the first index of the array Set int value i to 0 to use as the index Set int value found to 0 for not found (to be used as boolean 0 - not found, 1 - found) while (i < n && not found) { if (a[first+i] is the desired item) set found to 1 else increment i } if (found) The desired element was found at a[first+i]. else The desired element was not found in the array.
2.1.2 – Time Complexity
The average case time complexity for a linear search is (n+1)/2 array accesses given a linear run time of O(n). A proof for this can be seen as follows:
Given an array of 5 elements there are five possible cases:
- Desired element is at arr[0]: there is 1 array access
- Desired element is at arr[1]: there are 2 array accesses
- Desired element is at arr[2]: there are 3 array accesses
- Desired element is at arr[3]: there are 4 array accesses
- Desired element is at arr[4]: there are 5 array accesses
This gives us an average case of = 15 and can be generalized as follows
2.2 – Binary Search
2.2.1 – Pseudocode
Parameters:
- arr – The array to be searched
- first – The first index of the part of the array to search
- size – The number of elements to search, starting at a[first]
- target – The element desired
- location – Reference to location where item was found
- found – Reference to boolean stating whether the item has been found
Precondition:
If size > 0, then first through first + size – 1 must be valid indexes for the array arr. Also, starting at arr[first], the next size elements are sorted in increasing order from small to large.
if (size <= 0) Set found to false else { middle = index of the approximate midpoint of the array segment; if (target == arr[middle]) Set that the target was found and location to middle else if (target < arr[middle]) search for the target in the area before the midpoint else if (target > arr[middle]) search for the target in the area after the midpoint }
2.2.2 – Time Complexity
The time complexity of binary search is bounded by O(log n).
Files Needed
#ifndef SORTER #define SORTER class sort{ public: // Default constructor sort(); void bubble(int * arr, size_t size); void insertion(int * arr, size_t size); void selection(int * arr, size_t size); void mergesort(int * arr, size_t size); void merge(int * arr, size_t size1, size_t size2); void quicksort(int * arr, size_t size); void partition(int * arr, size_t size, size_t & pivot); }; #endif
sort.cpp
#include <iostream> #include "sort.h" sort :: sort() { // Do nothing } /* Precondition: arr is an integer array containing at least size components Postcondition: The elements in the array arr has been sorted so that arr[0] <= arr[1] <= ... <= arr[size-1] */ void sort :: bubble(int * arr, size_t size) { // YOUR CODE HERE } /* Precondition: arr is an integer array containing at least size components Postcondition: The elements in the array arr has been sorted so that arr[0] <= arr[1] <= ... <= arr[size-1] */ void sort :: insertion(int * arr, size_t size) { // YOUR CODE HERE } /* Precondition: arr is an integer array containing at least size components Postcondition: The elements in the array arr have been sorted so that arr[0] <= arr[1] <= ... <= arr[size-1] */ void sort :: selection(int * arr, size_t size) { // YOUR CODE HERE } /* Precondition: arr is an integer array containing at least size components Postcondition: The elements of the integer array arr have been sorted so that arr[0] <= arr[1] <= ... <= arr[size-1] NOTE: If there is insufficient dynamic memory, then bad_alloc is thrown. Library facilities used: cstdlib */ void sort :: mergesort(int * arr, size_t size) { // YOUR CODE HERE } /* Precondition: arr is an integer array (or subarray) with at least size1 + size2 elements. The first size1 elements (from arr[0] to arr[size1 - 1]) are sorted from smallest to largest, and the last size2 elements (from arr[size1] to arr[size1 + size2 - 1]) also are sorted from smallest to largest Postcodition: The first size1 + size2 elements of the integer array arr have been rearranged to be sorted from smallest to largest. NOTE: If there is insufficient dynamic memory, then bad_alloc is thrown. Library facilities used: cstdlib */ void sort :: merge(int * arr, size_t size1, size_t size2) { // YOUR CODE HERE } /* Precondition: arr is an integer array containing at least size components. Postcondition: The elements of arr have been rearranged so that arr[0] <= arr[1] <= ... <= arr[size-1] Library facilities used: cstdlib */ void sort :: quicksort(int * arr, size_t size) { // YOUR CODE HERE } /* Precondition: The number of elements size > 1 and arr is an integer array (or subarray) containing at least size elements. Postcondition: The function has selected some "pivot value" that occurs in arr[0]...arr[size-1]. The elements of arr have then been rearranged and the pivot index set so that --- arr[pivot_index] is equal to the pivot --- each element before arr[pivot_index] is <= the pivot --- each element after arr[pivot_index] is > the pivot */ void sort :: partition(int * arr, size_t size, size_t & pivot) { // YOUR CODE HERE }
main.cpp (for sorting)
#include <iostream> #include "sort.h" int main(int argc, char ** argv) { sort s; std::cout << "\nStarting bubble sort \n"; int arr[6] = {5,3,1,6,2,7}; s.bubble(arr, 6); for (int i = 0; i < 6; i++) { std::cout << arr[i] << std::endl; } std::cout << "\nStarting insertion sort \n"; int arr2[8] = {13, 6, 7, 21, 45, 9, 2, 100}; s.insertion(arr2, 8); for (int i = 0; i < 8; i++) { std::cout << arr2[i] << std::endl; } std::cout << "\nStarting selection sort \n"; int arr3[16] = {5, 1, 291, 21, 45, 643, 12, 11, 41, 23, 35 ,46, 51, 231, 21, 7}; s.selection(arr3, 16); for (int i = 0; i < 16; i++) { std::cout << arr3[i] << std::endl; } }
search.h
#ifndef SEARCHER #define SEARCHER class search{ public: // Default constructor search(); void serial (int * arr, size_t size, int target); void binary (const int * arr, size_t first, size_t size, int target, bool& found, size_t& location); }; #endif
search.cpp
#include <iostream> #include "search.h" search :: search() { // Do Nothing } /* Searches for a desired item in the size array elements starting at arr[first] Precondition: arr is an integer array containing size elements Postcondition: Display to the user whether the desired target was located */ void search :: serial (int * arr, size_t size, int target) { // YOUR CODE HERE } /* Precondition: The integer array segment starting at arr[first] and containing size elements is sorted from smallest to largest. Postcondition: The integer array segment starting at arr[first] and containg size elements has been searched for the target. If the target was present, then found is true, and location is set so that target --- arr[location]. Otherwise, found is set to false. Library facilities used: cstdlib (provides size_t from namespace std) */ void search :: binary (const int * arr, size_t first, size_t size, int target, bool& found, size_t& location) { // YOUR CODE HERE }
main.cpp
#include <iostream> #include "search.h" int main(int argc, char ** argv) { search s; int arr[10] = {1, 3, 5, 7, 11, 13, 17, 19, 21, 23}; s.serial(arr, 10, 11); s.serial(arr, 10, 100); bool found; size_t location; s.binary(arr, 0, 10, 19, found, location); if (found) std::cout << "Found at location: " << location << std::endl; else std::cout << "Not found\n"; s.binary(arr, 0, 10, 4, found, location); if (found) std::cout << "Found at location: " << location << std::endl; else std::cout << "Not found\n"; return 0; }
Extra Credit
EC 1
Each term appearing in the Fibonacci sequence is the sum of the previous two terms in the sequence. Starting with the two terms 0 and 1 the first 10 terms in the sequence will be
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …
Using an iterative approach to generating the Fibonacci sequence, create a program that will find the sum of all even terms less than 4 million. Expected output: 4613732
EC 2
Implement Mergesort and Merge in sort.cpp and demo its functionality in main.cpp
EC 3
Implement Partition and Quicksort in sort.cpp and demo its functionality in main.cpp
What to submit?
Lab3_LastName_FirstName.zip
|
|—–> Lab 3
| |
| |—–>Sorting
| | |
| | |—–>sort.h
| | |
| | |—–>sort.cpp
| | |
| | |—–>main.cpp
| | |
| | |—–>Makefile
| |
| |—–>Searching
| | |
| | |—–>search.h
| | |
| | |—–>search.cpp
| | |
| | |—–>main.cpp
| | |
| | |—–>Makefile
| |
| |—–>ExtraCredit
| | |
| | |—–>ec1.cpp
| | |
| | |—–>Makefile