Checkpoint #3

  • build sort into data structure
  • perform BigO analysis and evaluation of best sorts from CB, use sorts from others to compare to yours
  • support Analysis with runtime data, also analyze number of compares and swaps. Consider space complexity
public class SelectionSort {

    public int comparisons = 0; // creates primitive data types 
    public int swaps = 0; // public so it's used by both methods

    public static void main(String[] args) { // main method

        long start = 0; // initializes long which is a primitive data type that stores whole numbers. common type of initialization for a counter or timer that needs to be incremented or decremented as part of a program's logic
        long end = 0;

        // create a new SelectionSort object
        SelectionSort selectionSort = new SelectionSort();
 
        for (int i=0;i<12;i++) { // create 12 arrays as per requirements
        // generate 5000 random elements
            int[] array = new int[5000]; // creates a new array with 5000 integer
            for (int j=0;j<5000;j++) {
            array[j] = (int)(Math.random()*5000000);
            } // for loop generates the elements using random (math.random is only 0-1 so you mulitiply by 5000000 to get bigger number)
            // sort the array
            start += System.currentTimeMillis(); // before you start the sorting, it stores the current time
            selectionSort.sort(array); // sorts
            end += System.currentTimeMillis(); // stores the end time
        } 
        // get average
        System.out.println("Average time taken: " + (end-start)/12 + " ms");
        System.out.println("Average comparisons: " + selectionSort.comparisons/12); 
        System.out.println("Average swaps: " + selectionSort.swaps/12);
    }

    public void sort(int[] numbers) { // selection sort algorithm
        int n = numbers.length; // figures out the length of the array
                
        for (int i = 0; i < n - 1; i++) { // for loop used to repeatedly finds the minimum value and swaps it
            int minIndex = i; // outer loop iterates through array numbers and the minimum value is set to i
            
            for (int j = i + 1; j < n; j++) { // The inner loop  iterates through unsorted portion of the array after the current index i to the last element the algorithm compares the current element with the minimum element found so far

 
                comparisons++; // records the number of comparision 
                if (numbers[j] < numbers[minIndex]) { // inside loop checks if the index is different from the current value
                    minIndex = j; // if it is, the current value is set as the index 
                }
            }
        
            if (minIndex != i) { // stores value of first element in the temp variable and then copying the value of the temporary variable to the minimum element's original position 
                int temp = numbers[i];
                numbers[i] = numbers[minIndex];
                numbers[minIndex] = temp;
                swaps++; // number of swaps is implementing
            }
        }
        
        System.out.println("Comparisons: " + comparisons);
        System.out.println("Swaps: " + swaps);
    }
}

SelectionSort.main(null);
Comparisons: 12497500
Swaps: 4990
Comparisons: 24995000
Swaps: 9980
Comparisons: 37492500
Swaps: 14974
Comparisons: 49990000
Swaps: 19963
Comparisons: 62487500
Swaps: 24957
Comparisons: 74985000
Swaps: 29948
Comparisons: 87482500
Swaps: 34937
Comparisons: 99980000
Swaps: 39925
Comparisons: 112477500
Swaps: 44917
Comparisons: 124975000
Swaps: 49905
Comparisons: 137472500
Swaps: 54901
Comparisons: 149970000
Swaps: 59887
Average time taken: 14 ms
Average comparisons: 12497500
Average swaps: 4990

Evaluation:

  • selection sort: 14 ms // O(n^2)
  • insertion sort: 6ms // O(n^2)
  • merge sort: 14 ms // O(nlogn)
  • bubble sort: 22 ms // O(n^2)
  • these are the big O notaitons for the average cases, for example, in a best case inesertion sort it could be O(n)
  • insertion sort is the fastest even though it has the highest number of swaps. When I googled it, it said that Insertion sort is faster because it "has less overhead" which basically means that it requires less extra resources (memory, processor, time) than other algorithms.

HashMap example

import java.util.HashMap;
import java.util.Random;

public class ExampleHashMapSearch {
    public static void main(String[] args) {
        // Create a new HashMap object with 5000 elements
        HashMap<Integer, String> myHashMap = new HashMap<>();
        for (int i = 0; i < 5000; i++) {
            myHashMap.put(i, "value_" + i);
        } 

        // Perform 12 searches with random keys
        int numSearches = 12; // search for 12 different elements 
        int numKeys = 100; 
        int[] searchTimes = new int[numSearches];
        Random rand = new Random();
        for (int i = 0; i < numSearches; i++) {
            // Generate random keys to search for
            int[] keys = new int[numKeys];
            for (int j = 0; j < numKeys; j++) {
                keys[j] = rand.nextInt(5000);
            }

            // Search for the keys and record the time taken
            long startTime = System.nanoTime();
            for (int j = 0; j < numKeys; j++) {
                myHashMap.get(keys[j]);
            }
            long endTime = System.nanoTime();
            searchTimes[i] = (int) ((endTime - startTime));  // Convert nanoseconds to milliseconds
        }

        // Calculate the average search time
        int sum = 0;
        for (int i = 0; i < numSearches; i++) {
            sum += searchTimes[i];
        }
        int avg = sum / numSearches;

        // Print the results
        System.out.println("Average search time: " + avg + " nanoseconds");
    }
}
ExampleHashMapSearch.main(null);
Average search time: 19434 nanoseconds
  • Hashmap is O(1)
  • Binary Search is O(logn) divides into 2