160 likes | 277 Views
Lecture 16: Searching and Sorting Arrays. Professor: Dr. Miguel Alonso Jr. Fall 2008 CGS2423/COP1220. Outline. Introduction to Search Algorithms Case Study Introduction to Sorting Algorithms Case Study. Introduction to Search Algorithms.
E N D
Lecture 16: Searching and Sorting Arrays Professor: Dr. Miguel Alonso Jr. Fall 2008 CGS2423/COP1220
Outline • Introduction to Search Algorithms • Case Study • Introduction to Sorting Algorithms • Case Study
Introduction to Search Algorithms • Concept: A search algorithm is a method of locating a specific item in a larger collection of data. • Linear Search • Binary Search
Linear Search • Also called sequential search • Uses a loop to sequentially step through the array, starting with the first element • Compares each element with the value being searched for • If the value is being searched for is not in the array, the algorithm will unsuccessfully search until the end of the array
set found to false set position to -1 set index to 0 while found is false and index < number of elements if list[index] is equal to search value found = true position = index end if add 1 to index end while return position // This program demonstrates the searchList function, which // performs a linear search on an integer array. #include <iostream> using namespace std; // Function prototype intsearchList(int [], int, int); const int SIZE = 5; int main() { int tests[SIZE] = {87, 75, 98, 100, 82}; int results; // Search the array for 100. results = searchList(tests, SIZE, 100); // If searchList returned -1, then 100 was not found. if (results == -1) cout << "You did not earn 100 points on any test\n"; else { // Otherwise results contains the subscript of // the first 100 in the array. cout << "You earned 100 points on test "; cout << (results + 1) << endl; } return 0; } //***************************************************************** // The searchList function performs a linear search on an * // integer array. The array list, which has a maximum of numElems * // elements, is searched for the number stored in value. If the * // number is found, its array subscript is returned. Otherwise, * // -1 is returned indicating the value was not in the array. * //***************************************************************** intsearchList(int list[], intnumElems, 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 }
Pros and Cons • Advantages • Simple • Does not require data to be sorted • Disadvantages • Inefficient: if the array contains 20,000 elements, the worst case will be 20,000 loops and comparisons • On average, an elements likelihood of being found at the beginning is equal to the likelihood of being found at the end • For an array of N items, there will be N/2 comparisons, (on average)
Binary Search • Much more efficient than the Linear search • The array must be sorted in order • Instead of testing the first element, the algorithm starts with the element in the middle • If that is the element the search is over • if not, the value in the middle is either larger or smaller than the value being searched for • if greater, then the desired value is in the lower half • if less, then the desired value is the upper half • repeat for the upper/lower half
set first index to 0 set last index to the last subscript of the array set found to false set position = -1 while found is not true and first is less than or equal to last set middle to the subscript halfway between array[first] and array[last] if array[middle] equals the desired value set found = true set position = middle else if array[middle] is greater than the desired value set last = middle -1 else set first to middle + 1 end if end while return position // This program demonstrates the binarySearch function, which // performs a binary search on an integer array. #include <iostream> using namespace std; // Function prototype intbinarySearch(int [], int, int); const int SIZE = 20; int main() { // Array with employee IDs sorted in ascending order. intidNums[SIZE] = {101, 142, 147, 189, 199, 207, 222, 234, 289, 296, 310, 319, 388, 394, 417, 429, 447, 521, 536, 600}; int results; // To hold the search results intempID; // To hold an employee ID // Get an employee ID to search for. cout << "Enter the employee ID you wish to search for: "; cin >> empID; // Search for the ID. results = binarySearch(idNums, SIZE, empID); // If results contains -1 the ID was not found. if (results == -1) cout << "That number does not exist in the array.\n"; else { // Otherwise results contains the subscript of // the specified employee ID in the array. cout << "That ID is found at element " << results; cout << " in the array.\n"; } return 0; } //*************************************************************** // The binarySearch function performs a binary search on an * // integer array. array, which has a maximum of size elements, * // is searched for the number stored in value. If the number is * // found, its array subscript is returned. Otherwise, -1 is * // returned indicating the value was not in the array. * //*************************************************************** intbinarySearch(int array[], int size, int value) { int first = 0, // First array element last = size - 1, // Last array element middle, // Mid point of search position = -1; // Position of search value bool found = false; // Flag while (!found && first <= last) { middle = (first + last) / 2; // Calculate mid point if (array[middle] == value) // If value is found at mid { found = true; position = middle; } else if (array[middle] > value) // If value is in lower half last = middle - 1; else first = middle + 1; // If value is in upper half } return position; }
The efficiency of the binary search • With every comparison, half of the array is eliminated! • How many comparisons are needed? • Powers of 2 are used to compute • Find the smallest power of 2 that is greater than or equal to the number of elements in the array • Example: For an array of 50,000 elements, 16 comparisons will be made because 216 = 65,536 and 216 = 32,768
Searching Case Study: // Demetris Leadership Center (DLC) product lookup program // This program allows the user to enter a product number // and then displays the title, description, and price of // that product. #include <iostream> using namespace std; const int NUM_PRODS = 9; // The number of products produced const int TITLE_SIZE = 26; // The max size of a title string const int DESC_SIZE = 12; // The max size of a desc. string const int MIN_PRODNUM = 914; // The lowest product number const int MAX_PRODNUM = 922; // The highest product number // Function prototypes intgetProdNum(); intbinarySearch(int [], int, int); void displayProd(char [][TITLE_SIZE], char [][DESC_SIZE], double [], int); int main() { // Array of product IDs int id[NUM_PRODS] = {914, 915, 916, 917, 918, 919, 920, 921, 922}; // Array of product titles char title[NUM_PRODS][TITLE_SIZE] = { "Six Steps to Leadership", "Six Steps to Leadership", "The Road to Excellence", "Seven Lessons of Quality", "Seven Lessons of Quality", "Seven Lessons of Quality", "Teams Are Made, Not Born", "Leadership for the Future", "Leadership for the Future" }; // Array of product descriptions char description[NUM_PRODS][DESC_SIZE] = { "Book", "Audio CD", "DVD", "Book", "Audio CD", "DVD", "Book", "Book", "Audio CD" }; // Array of product prices double prices[NUM_PRODS] = {12.95, 14.95, 18.95, 16.95, 21.95, 31.95, 14.95, 14.95, 16.95}; intprodNum; // To hold a product number int index; // To hold search results char again; // To hold a Y or N answer do { // Get the desired product number. prodNum = getProdNum(); // Search for the product number. index = binarySearch(id, NUM_PRODS, prodNum); // Display the results of the search. if (index == -1) cout << "That product number was not found.\n"; else displayProd(title, description, prices, index); // Does the user want to do this again? cout << "Would you like to look up another product? (y/n) "; cin >> again; } while (again == 'y' || again == 'Y'); return 0; } //*************************************************** // Definition of getProdNum function * // The getProdNum function asks the user to enter a * // product number. The input is validated, and when * // a valid number is entered, it is returned. * //*************************************************** intgetProdNum() { intprodNum; // Product number cout << "Enter the item's product number: "; cin >> prodNum; // Validate input while (prodNum < MIN_PRODNUM || prodNum > MAX_PRODNUM) { cout << "Enter a number in the range of " << MIN_PRODNUM; cout <<" through " << MAX_PRODNUM << ".\n"; cin >> prodNum; } return prodNum; } //*************************************************************** // Definition of binarySearch function * // The binarySearch function performs a binary search on an * // integer array. array, which has a maximum of numElems * // elements, is searched for the number stored in value. If the * // number is found, its array subscript is returned. Otherwise, * // -1 is returned indicating the value was not in the array. * //*************************************************************** intbinarySearch(int array[], intnumElems, int value) { int first = 0, // First array element last = numElems - 1, // Last array element middle, // Mid point of search position = -1; // Position of search value bool found = false; // Flag while (!found && first <= last) { middle = (first + last) / 2; // Calculate mid point if (array[middle] == value) // If value is found at mid { found = true; position = middle; } else if (array[middle] > value) // If value is in lower half last = middle - 1; else first = middle + 1; // If value is in upper half } return position; } //************************************************************ // The displayProd function accepts three arrays and an int. * // The arrays parameters are expected to hold the title, * // description, and prices arrays defined in main. The * // ndx parameter holds a subscript. This function displays * // the information in each array contained at the subscript. * //************************************************************ void displayProd(char title[][TITLE_SIZE], char desc[][DESC_SIZE], double price[], int index) { cout << "Title: " << title[index] << endl; cout << "Description: " << desc[index] << endl; cout << "Price: $" << price[index] << endl; }
Introduction to Sorting • Concept: Sorting algorithms are used to arrange data into some order • Bubble sort • Selection Sort
Bubble Sort • Easy way to arrange data in ascending or descending order • Ascending: from lowest to highest • Descending: from highest to lowest • How it works: Repeatedly steps through the list to be sorted, comparing two items at a time and swapping them if they are in the wrong order • The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted.
First Pass:( 51 4 2 8 ) ( 15 4 2 8 ) Here, algorithm compares the first two elements, and swaps them.( 1 54 2 8 ) ( 1 45 2 8 )( 1 4 52 8 ) ( 1 4 25 8 )( 1 4 2 58 ) ( 1 4 2 58 ) Now, since these elements are already in order, algorithm does not swap them.Second Pass:( 14 2 5 8 ) ( 14 2 5 8 )( 1 42 5 8 ) ( 1 24 5 8 )( 1 2 45 8 ) ( 1 2 45 8 )( 1 2 4 58 ) ( 1 2 4 58 )Now, the array is already sorted, but our algorithm does not know if it is completed. Algorithm needs one whole pass without any swap to know it is sorted.Third Pass:( 12 4 5 8 ) ( 12 4 5 8 )( 1 24 5 8 ) ( 1 24 5 8 )( 1 2 45 8 ) ( 1 2 45 8 )( 1 2 4 58 ) ( 1 2 4 58 )Finally, the array is sorted, and the algorithm can terminate. // This program uses the bubble sort algorithm to sort an // array in ascending order. #include <iostream> using namespace std; // Function prototypes void sortArray(int [], int); void showArray(int [], int); int main() { // Array of unsorted values int values[6] = {7, 2, 3, 8, 9, 1}; // Display the values. cout << "The unsorted values are:\n"; showArray(values, 6); // Sort the values. sortArray(values, 6); // Display them again. cout << "The sorted values are:\n"; showArray(values, 6); return 0; } //*********************************************************** // Definition of function sortArray * // This function performs an ascending order bubble sort on * // array. size is the number of elements in the array. * //*********************************************************** 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]) { temp = array[count]; array[count] = array[count + 1]; array[count + 1] = temp; swap = true; } } } while (swap); } //************************************************************* // Definition of function showArray. * // This function displays the contents of array. size is the * // number of elements. * //************************************************************* void showArray(int array[], int size) { for (int count = 0; count < size; count++) cout << array[count] << " "; cout << endl; } Do set swap flag to false for(int count = 0; count < (size -1); count++ if array[count] is greater than array[count+1] swap set swap flag to true end if end for While swap flag is true
Selection Sort • Bubble sort is inefficient for large arrays • Selection sort is more efficient and performs fewer exchanges because it moves items immediately to their final position in the array • The smallest value is located and moved to element zero • The next smallest value is located and moved to element 1 • and so on…
572891172895 172895 127895 127895 125897 125897 125798 125798 125789 // This program uses the selection sort algorithm to sort an // array in ascending order. #include <iostream> using namespace std; // Function prototypes void selectionSort(int [], int); void showArray(int [], int); int main() { // Define an array with unsorted values const int SIZE = 6; int values[SIZE] = {5, 7, 2, 8, 9, 1}; // Display the values. cout << "The unsorted values are\n"; showArray(values, SIZE); // Sort the values. selectionSort(values, SIZE); // Display the values again. cout << "The sorted values are\n"; showArray(values, SIZE); return 0; } //************************************************************** // Definition of function selectionSort. * // This function performs an ascending order selection sort on * // array. size is the number of elements in the array. * //************************************************************** void selectionSort(int array[], int size) { intstartScan, 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; } } //************************************************************** // Definition of function showArray. * // This function displays the contents of array. size is the * // number of elements. * //************************************************************** void showArray(int array[], int size) { for (int count = 0; count < size; count++) cout << array[count] << " "; cout << endl; } for (startScan = 0; startScan < (size - 1); startScan++) set minIndex variable to startScan set minValue variable to array[startScan] for(int index = startScan + 1; index < size; index++) if array[index] is less than minValue set minValue to array[index] set minIndex to index end if end for array[minIndex] to array[startScan] array[startScan] to minValue
Sorting Case Study // This program produces a sales report for DLC, Inc. #include <iostream> #include <iomanip> using namespace std; // Function prototypes void calcSales(int [], double [], double [], int); void showOrder(double [], int [], int); void dualSort(int [], double [], int); void showTotals(double [], int [], int); // NUM_PRODS is the number of products produced. const int NUM_PRODS = 9; int main() { // Array with product ID numbers int id[NUM_PRODS] = {914, 915, 916, 917, 918, 919, 920, 921, 922}; // Array with number of units sold for each product int units[NUM_PRODS] = {842, 416, 127, 514, 437, 269, 97, 492, 212}; // Array with product prices double prices[NUM_PRODS] = {12.95, 14.95, 18.95, 16.95, 21.95, 31.95, 14.95, 14.95, 16.95}; // Array to hold the computed sales amounts double sales[NUM_PRODS]; // Calculate each product's sales. calcSales(units, prices, sales, NUM_PRODS); // Sort the elements in the sales array in descending // order and shuffle the ID numbers in the id array to // keep them in parallel. dualSort(id, sales, NUM_PRODS); // Set the numeric output formatting. cout << setprecision(2) << fixed << showpoint; // Display the products and sales amounts. showOrder(sales, id, NUM_PRODS); // Display total units sold and total sales. showTotals(sales, units, NUM_PRODS); return 0; } //**************************************************************** // Definition of calcSales. Accepts units, prices, and sales * // arrays as arguments. The size of these arrays is passed * // into the num parameter. This function calculates each * // product's sales by multiplying its units sold by each unit's * // price. The result is stored in the sales array. * //**************************************************************** void calcSales(int units[], double prices[], double sales[], int num) { for (int index = 0; index < num; index++) sales[index] = units[index] * prices[index]; } //*************************************************************** // Definition of function dualSort. Accepts id and sales arrays * // as arguments. The size of these arrays is passed into size. * // This function performs a descending order selection sort on * // the sales array. The elements of the id array are exchanged * // identically as those of the sales array. size is the number * // of elements in each array. * //*************************************************************** void dualSort(int id[], double sales[], int size) { intstartScan, maxIndex, tempid; double maxValue; for (startScan = 0; startScan < (size - 1); startScan++) { maxIndex = startScan; maxValue = sales[startScan]; tempid = id[startScan]; for(int index = startScan + 1; index < size; index++) { if (sales[index] > maxValue) { maxValue = sales[index]; tempid = id[index]; maxIndex = index; } } sales[maxIndex] = sales[startScan]; id[maxIndex] = id[startScan]; sales[startScan] = maxValue; id[startScan] = tempid; } } //**************************************************************** // Definition of showOrder function. Accepts sales and id arrays * // as arguments. The size of these arrays is passed into num. * // The function first displays a heading, then the sorted list * // of product numbers and sales. * //**************************************************************** void showOrder(double sales[], int id[], int num) { cout << "Product Number\tSales\n"; cout << "----------------------------------\n"; for (int index = 0; index < num; index++) { cout << id[index] << "\t\t$"; cout << setw(8) << sales[index] << endl; } cout << endl; } //***************************************************************** // Definition of showTotals function. Accepts sales and id arrays * // as arguments. The size of these arrays is passed into num. * // The function first calculates the total units (of all * // products) sold and the total sales. It then displays these * // amounts. * //***************************************************************** void showTotals(double sales[], int units[], int num) { inttotalUnits = 0; double totalSales = 0.0; for (int index = 0; index < num; index++) { totalUnits += units[index]; totalSales += sales[index]; } cout << "Total units Sold: " << totalUnits << endl; cout << "Total sales: $" << totalSales << endl; }