Learning About the different Sorts -- Bubble

  • Bubble Sort: allows you to sort items in an array in ascending order. Each value checks with the one to its right and sees if it's less than, greater than, or equal. If the value is less than or equal to the one to its right, no change will occur. However, if it's greater than the value to its right, a swap occurs.

Hack 1 -- Bubble Sort

public class BubbleSort {
   
  //method to sort an array using Bubble sort  
  public static void bubbleSort(int[] arr) {
      int n = arr.length;
      for (int i = 0; i < n - 1; i++) {
        //loop through unsorted portion of array    
        for (int j = 0; j < n - i - 1; j++) {
            //If current element is greater than next element, swap
              if (arr[j] > arr[j + 1]) {
                  // swap
                  int temp = arr[j];
                  arr[j] = arr[j + 1];
                  arr[j + 1] = temp;
              }
          }
      }
  }
  
  // Main method to test BubbleSort class
  public static void main(String[] args) {
      int[] arr = {5, 2, 9, 1, 5, 6};
      System.out.println("Array before sorting:");
      for (int i = 0; i < arr.length; i++) {
          System.out.print(arr[i] + " ");
      }
      
      bubbleSort(arr);
      
      System.out.println("\nArray after sorting:");
      for (int i = 0; i < arr.length; i++) {
          System.out.print(arr[i] + " ");
      }
  }
}
BubbleSort.main(null);
Array before sorting:
5 2 9 1 5 6 
Array after sorting:
1 2 5 5 6 9 

Learning About the Different Sorts -- Selection

  • Selection Sort: Can sort in either ascending or descending order. Start by finding the smallest value in the array and putting it at the front or end of the array.

Hack 2 -- Selection Sort

public class SelectionSort {
    
  public static void selectionSort(int[] arr) {
      int n = arr.length;
      
      for (int i = 0; i < n - 1; i++) {
          int minIndex = i;
          
          // Find the minimum element in unsorted part of array
          for (int j = i + 1; j < n; j++) {
              if (arr[j] < arr[minIndex]) {
                  minIndex = j;
              }
          }
          
          // Swap the found minimum element with the first element
          int temp = arr[minIndex];
          arr[minIndex] = arr[i];
          arr[i] = temp;
      }
  }
  
  // Printing out the sorted and unsorted arrays 
  public static void main(String[] args) {
      int[] arr = {5, 2, 9, 1, 5, 6};
      System.out.println("Array before sorting:");
      for (int i = 0; i < arr.length; i++) {
          System.out.print(arr[i] + " ");
      }
      
      selectionSort(arr);
      
      System.out.println("\nArray after sorting:");
      for (int i = 0; i < arr.length; i++) {
          System.out.print(arr[i] + " ");
      }
  }
}

SelectionSort.main(null);
Array before sorting:
5 2 9 1 5 6 
Array after sorting:
1 2 5 5 6 9 

Learning About the Different Sorts -- Insertion

  • Insertion Sort: Compares the value with the value to its right. If it's greater, the two swap positions. However, if the number on right is less than the one on the left and all the ones behind it, the value gets moved to the back.

Hack 3 -- Insertion Sort

public class InsertionSort {
    
    public static void insertionSort(int[] arr) {
        int n = arr.length;
        
        for (int i = 1; i < n; i++) {
            int key = arr[i];
            int j = i - 1;
            
            // Move elements of arr[0..i-1], that are greater than key, to one position ahead of their current position
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j--;
            }
            
            arr[j + 1] = key;
        }
    }
    
    //Testing InsertionSort
    public static void main(String[] args) {
        int[] arr = {5, 2, 9, 1, 5, 6};
        System.out.println("Array before sorting:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        
        insertionSort(arr);
        
        System.out.println("\nArray after sorting:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

InsertionSort.main(null);
Array before sorting:
5 2 9 1 5 6 
Array after sorting:
1 2 5 5 6 9 

Learning About the Different Sorts -- Merge

  • Merge Sort: Takes an array and keeps splitting it in half until every value in the array is isolated. Then sorts through those independent values and merges them together into an array again.

Hack 4 -- Merge Sort

public class Merge{
   
    public static void mergeSort(int[] arr) {
        // base case: array has 1 or 0 elements
        if (arr.length <= 1) {
            return;
        }
        
        // divide the array into two halves
        int mid = arr.length / 2;
        int[] left = Arrays.copyOfRange(arr, 0, mid);
        int[] right = Arrays.copyOfRange(arr, mid, arr.length);
        
        // recursively sort each half
        mergeSort(left);
        mergeSort(right);
        
        // merge the two sorted halves
        int i = 0;
        int j = 0;
        int k = 0;
        while (i < left.length && j < right.length) {
            if (left[i] <= right[j]) {
                arr[k] = left[i];
                i++;
            } else {
                arr[k] = right[j];
                j++;
            }
            k++;
        }
        while (i < left.length) {
            arr[k] = left[i];
            i++;
            k++;
        }
        while (j < right.length) {
            arr[k] = right[j];
            j++;
            k++;
        }
    }

    public static void main(String[] args) {
        int[] array = {7, 8, 2, 4, 5, 3};
        
        // sort the array using merge sort
        System.out.println("Unsorted array: " + Arrays.toString(array));
        mergeSort(array);
        System.out.println("Sorted array: " + Arrays.toString(array)); 
    }
}

Merge.main(null);
Unsorted array: [7, 8, 2, 4, 5, 3]
Sorted array: [2, 3, 4, 5, 7, 8]

Actual Hack 1: Testing Out The Sorts

  • The following code will run the different sorts and record the time and efficiency of running these sorts. After we will analyze with Big O Notation
public class SortAnalysis {
    // generate array of 5000 integers
    public static int[] generateArray() {
        int[] arr = new int[5000];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * 10000);
        }
        return arr;
    }
    
    public static float[] main(String[] args) {

        System.out.println("-------------------------------");

        // create an array with 5000 elements
        int[] arr1 = generateArray();
        int[] arr2 = new int[5000];
        int[] arr3 = new int[5000];
        int[] arr4 = new int[5000];
        System.arraycopy(arr1, 0, arr2, 0, 5000);
        System.arraycopy(arr1, 0, arr3, 0, 5000);
        System.arraycopy(arr1, 0, arr4, 0, 5000);

        float[] times = new float[4];
        String str = "";

        // sort the array
        long start = System.nanoTime();
        bubbleSort(arr1);
        long end = System.nanoTime();
        // print the time it took
        str += ((end - start) + "ns | ");
        times [0] = (end - start);

        start = System.nanoTime();
        mergeSort(arr2);
        end = System.nanoTime();
        // print the time it took
        str += ((end - start) + "ns | ");
        times [1] = (end - start);

        start = System.nanoTime();
        selectionSort(arr3);
        end = System.nanoTime();
        // print the time it took
        str += ((end - start) + "ns | ");
        times [2] = (end - start);

        start = System.nanoTime();
        insertionSort(arr4);
        end = System.nanoTime();
        // print the time it took
        str += ((end - start) + "ns");
        times [3] = (end - start);
        System.out.println(str);

        return times;
    }

    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // swap arr[j] and arr[j+1]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    // instertionsort from before
    public static void insertionSort(int[] arr) {
        int n = arr.length;
        
        for (int i = 1; i < n; i++) {
            int key = arr[i];
            int j = i - 1;
            
            // Move elements of arr[0..i-1], that are greater than key, to one position ahead of their current position
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j--;
            }
            
            arr[j + 1] = key;
        }
    }

    // selectionsort from before
    public static void selectionSort(int[] arr) {
        int n = arr.length;
        
        for (int i = 0; i < n - 1; i++) {
            int minIndex = i;
            
            // Find the minimum element in unsorted part of array
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            
            // Swap the found minimum element with the first element
            int temp = arr[minIndex];
            arr[minIndex] = arr[i];
            arr[i] = temp;
        }
    }

    // mergesort from previous lesson
    public static void mergeSort(int[] arr) {
        if (arr.length > 1) {
            int[] left = leftHalf(arr);
            int[] right = rightHalf(arr);

            mergeSort(left);
            mergeSort(right);

            merge(arr, left, right);
        }
    }

    // lefthalf function for mergesort
    public static int[] leftHalf(int[] arr) {
        int size1 = arr.length / 2;
        int[] left = new int[size1];
        for (int i = 0; i < size1; i++) {
            left[i] = arr[i];
        }
        return left;
    }

    // righthalf function for mergesotr
    public static int[] rightHalf(int[] arr) {
        int size1 = arr.length / 2;
        int size2 = arr.length - size1;
        int[] right = new int[size2];
        for (int i = 0; i < size2; i++) {
            right[i] = arr[i + size1];
        }
        return right;
    }

    public static int[] merge(int[] result, int[] left, int[] right) {
        int i1 = 0;
        int i2 = 0;

        for (int i = 0; i < result.length; i++) {
            if (i2 >= right.length || (i1 < left.length && left[i1] <= right[i2])) {
                result[i] = left[i1];
                i1++;
            } else {
                result[i] = right[i2];
                i2++;
            }
        }
        return result;
    }
}
   


System.out.println("Bubble | Merge | Selection | Insertion");
float[] means = new float[4];


for (int i = 0; i < 12; i++) {
    float[] a = SortAnalysis.main(null);
    
    for (int j = 0; j < 4; j++) {
        means[j] += a[j];
    }
}

for (int i = 0; i < 4; i++) {
    means[i] /= 12;
    means[i] = Math.round(means[i] * 1000) / 1000;
}

System.out.println("-------------------------------");
System.out.println("Average: " + means[0] + "ns | " + means[1] + "ns | " + means[2] + "ns | " + means[3] + "ns");
Bubble | Merge | Selection | Insertion
-------------------------------
26359132ns | 384839ns | 11816900ns | 1256602ns
-------------------------------
33477006ns | 413954ns | 11202658ns | 1328927ns
-------------------------------
29693041ns | 331956ns | 7299627ns | 1236973ns
-------------------------------
26638518ns | 535161ns | 10510700ns | 1923411ns
-------------------------------
23286905ns | 365315ns | 7529654ns | 989740ns
-------------------------------
27035507ns | 334038ns | 12639705ns | 1921034ns
-------------------------------
33890913ns | 407079ns | 12685304ns | 1047968ns
-------------------------------
27578112ns | 327123ns | 12292588ns | 1355634ns
-------------------------------
42378441ns | 960447ns | 9081393ns | 1682118ns
-------------------------------
29891726ns | 342660ns | 9673850ns | 1401839ns
-------------------------------
29002366ns | 1027379ns | 12980261ns | 1286304ns
-------------------------------
24768000ns | 338684ns | 9059800ns | 821362ns
-------------------------------
Average: 2147483.0ns | 480719.0ns | 2147483.0ns | 1354326.0ns

Big O Notation Notes

Merge Sort:
  • Time Complexity: O(n log n)
  • Number of Comparisons: O(n log n)
  • Number of Swaps: O(n log n) ##### Insertion Sort:
  • Time Complexity: O(n^2)
  • Number of Comparisons: O(n^2)
  • Number of Swaps: O(n^2) ##### Bubble Sort:
  • Time Complexity: O(n^2)
  • Number of Comparisons: O(n^2)
  • Number of Swaps: O(n^2) ##### Selection Sort:
  • Time Complexity: O(n^2)
  • Number of Comparisons: O(n^2)
  • Number of Swaps: O(n)

Extra Sort Notes

  • Quick Sort: This algorithm divides the list into two smaller sub-lists around a pivot element and recursively sorts each sub-list. The time complexity of Quick Sort is O(n log n) on average, which means that it can sort a list of n elements in roughly log n recursive steps, with each step taking O(n) time.
    • This algorithm transforms the list into a heap data structure, where each element is larger than its children (for a max heap). It then repeatedly removes the largest element from the heap and places it at the end of the list. The time complexity of Heap Sort is also O(n log n), because it needs to perform log n heapify operations for each of the n elements.

Hashmap Practice

  • Be sure to have 5000 records
  • Perform analysis on Binary Search vs HashMap Lookup, try using random to search and find 100 keys in 5000 records. Perform 12 times and throw out high and low.
import java.util.HashMap;

public class HashTester {
    public static void main(String[] args) {
        Map<String, String> hashMap = new HashMap<String, String>();
        for (int i = 0; i < 5000; i++) {
            hashMap.put("key" + i, "value" + i);
        }

        // List<Integer> key = new ArrayList<Integer>();
        // for (int i = 0, i < 100; i++){
        //     key.add(i);
        // }

        List<String> keys = new ArrayList<String>(hashMap.keySet());
        Collections.shuffle(keys);
        Collections.sort(keys);    
        long startTime = System.nanoTime();
        for (int i = 0; i < 100; i++) {
            // int index = Collections.binarySearch(keys, key);
            int index = Collections.binarySearch(keys, "key" + i);
            if (index >= 0) {
                System.out.println("Found key: " + keys.get(index) + " with value: " + hashMap.get(keys.get(index)));
            }
        }
        long elapsedTime = System.nanoTime() - startTime;

        long startTime2 = System.nanoTime();        
        for (int i = 0; i < 100; i++) {
            String key = "key" + i;
            if (hashMap.containsKey(key)) {
                System.out.println("Found key: " + key + " with value: " + hashMap.get(key));
            }
        }
        long elapsedTime2 = System.nanoTime() - startTime2;
        
        
        System.out.println("Time it took to complete Binary Search in milliseconds: " + elapsedTime/1000000);
        System.out.println("Time it took to complete Hash Search in milliseconds: " + elapsedTime2/1000000);

    }
}

HashTester.main(null);
Found key: key0 with value: value0
Found key: key1 with value: value1
Found key: key2 with value: value2
Found key: key3 with value: value3
Found key: key4 with value: value4
Found key: key5 with value: value5
Found key: key6 with value: value6
Found key: key7 with value: value7
Found key: key8 with value: value8
Found key: key9 with value: value9
Found key: key10 with value: value10
Found key: key11 with value: value11
Found key: key12 with value: value12
Found key: key13 with value: value13
Found key: key14 with value: value14
Found key: key15 with value: value15
Found key: key16 with value: value16
Found key: key17 with value: value17
Found key: key18 with value: value18
Found key: key19 with value: value19
Found key: key20 with value: value20
Found key: key21 with value: value21
Found key: key22 with value: value22
Found key: key23 with value: value23
Found key: key24 with value: value24
Found key: key25 with value: value25
Found key: key26 with value: value26
Found key: key27 with value: value27
Found key: key28 with value: value28
Found key: key29 with value: value29
Found key: key30 with value: value30
Found key: key31 with value: value31
Found key: key32 with value: value32
Found key: key33 with value: value33
Found key: key34 with value: value34
Found key: key35 with value: value35
Found key: key36 with value: value36
Found key: key37 with value: value37
Found key: key38 with value: value38
Found key: key39 with value: value39
Found key: key40 with value: value40
Found key: key41 with value: value41
Found key: key42 with value: value42
Found key: key43 with value: value43
Found key: key44 with value: value44
Found key: key45 with value: value45
Found key: key46 with value: value46
Found key: key47 with value: value47
Found key: key48 with value: value48
Found key: key49 with value: value49
Found key: key50 with value: value50
Found key: key51 with value: value51
Found key: key52 with value: value52
Found key: key53 with value: value53
Found key: key54 with value: value54
Found key: key55 with value: value55
Found key: key56 with value: value56
Found key: key57 with value: value57
Found key: key58 with value: value58
Found key: key59 with value: value59
Found key: key60 with value: value60
Found key: key61 with value: value61
Found key: key62 with value: value62
Found key: key63 with value: value63
Found key: key64 with value: value64
Found key: key65 with value: value65
Found key: key66 with value: value66
Found key: key67 with value: value67
Found key: key68 with value: value68
Found key: key69 with value: value69
Found key: key70 with value: value70
Found key: key71 with value: value71
Found key: key72 with value: value72
Found key: key73 with value: value73
Found key: key74 with value: value74
Found key: key75 with value: value75
Found key: key76 with value: value76
Found key: key77 with value: value77
Found key: key78 with value: value78
Found key: key79 with value: value79
Found key: key80 with value: value80
Found key: key81 with value: value81
Found key: key82 with value: value82
Found key: key83 with value: value83
Found key: key84 with value: value84
Found key: key85 with value: value85
Found key: key86 with value: value86
Found key: key87 with value: value87
Found key: key88 with value: value88
Found key: key89 with value: value89
Found key: key90 with value: value90
Found key: key91 with value: value91
Found key: key92 with value: value92
Found key: key93 with value: value93
Found key: key94 with value: value94
Found key: key95 with value: value95
Found key: key96 with value: value96
Found key: key97 with value: value97
Found key: key98 with value: value98
Found key: key99 with value: value99
Found key: key0 with value: value0
Found key: key1 with value: value1
Found key: key2 with value: value2
Found key: key3 with value: value3
Found key: key4 with value: value4
Found key: key5 with value: value5
Found key: key6 with value: value6
Found key: key7 with value: value7
Found key: key8 with value: value8
Found key: key9 with value: value9
Found key: key10 with value: value10
Found key: key11 with value: value11
Found key: key12 with value: value12
Found key: key13 with value: value13
Found key: key14 with value: value14
Found key: key15 with value: value15
Found key: key16 with value: value16
Found key: key17 with value: value17
Found key: key18 with value: value18
Found key: key19 with value: value19
Found key: key20 with value: value20
Found key: key21 with value: value21
Found key: key22 with value: value22
Found key: key23 with value: value23
Found key: key24 with value: value24
Found key: key25 with value: value25
Found key: key26 with value: value26
Found key: key27 with value: value27
Found key: key28 with value: value28
Found key: key29 with value: value29
Found key: key30 with value: value30
Found key: key31 with value: value31
Found key: key32 with value: value32
Found key: key33 with value: value33
Found key: key34 with value: value34
Found key: key35 with value: value35
Found key: key36 with value: value36
Found key: key37 with value: value37
Found key: key38 with value: value38
Found key: key39 with value: value39
Found key: key40 with value: value40
Found key: key41 with value: value41
Found key: key42 with value: value42
Found key: key43 with value: value43
Found key: key44 with value: value44
Found key: key45 with value: value45
Found key: key46 with value: value46
Found key: key47 with value: value47
Found key: key48 with value: value48
Found key: key49 with value: value49
Found key: key50 with value: value50
Found key: key51 with value: value51
Found key: key52 with value: value52
Found key: key53 with value: value53
Found key: key54 with value: value54
Found key: key55 with value: value55
Found key: key56 with value: value56
Found key: key57 with value: value57
Found key: key58 with value: value58
Found key: key59 with value: value59
Found key: key60 with value: value60
Found key: key61 with value: value61
Found key: key62 with value: value62
Found key: key63 with value: value63
Found key: key64 with value: value64
Found key: key65 with value: value65
Found key: key66 with value: value66
Found key: key67 with value: value67
Found key: key68 with value: value68
Found key: key69 with value: value69
Found key: key70 with value: value70
Found key: key71 with value: value71
Found key: key72 with value: value72
Found key: key73 with value: value73
Found key: key74 with value: value74
Found key: key75 with value: value75
Found key: key76 with value: value76
Found key: key77 with value: value77
Found key: key78 with value: value78
Found key: key79 with value: value79
Found key: key80 with value: value80
Found key: key81 with value: value81
Found key: key82 with value: value82
Found key: key83 with value: value83
Found key: key84 with value: value84
Found key: key85 with value: value85
Found key: key86 with value: value86
Found key: key87 with value: value87
Found key: key88 with value: value88
Found key: key89 with value: value89
Found key: key90 with value: value90
Found key: key91 with value: value91
Found key: key92 with value: value92
Found key: key93 with value: value93
Found key: key94 with value: value94
Found key: key95 with value: value95
Found key: key96 with value: value96
Found key: key97 with value: value97
Found key: key98 with value: value98
Found key: key99 with value: value99
Time it took to complete Binary Search in milliseconds: 2
Time it took to complete Hash Search in milliseconds: 4