package hw5;
import java.util.*;
/*
* Title: hw5.hw5_2.java
* Abstract: This program generates and array of random ints of a set size and tests heapSort,
mergeSort, and quickSort
* on them and logs out the speeds.
* heapsort from - https://www.geeksforgeeks.org/heap-sort/
* mergesort from - https://www.geeksforgeeks.org/merge-sort/
* quicksort from - https://www.geeksforgeeks.org/quick-sort/
* Author: Ryan Barrett
* ID: 2272
* Date: 04/13/2021
*/
public class hw5_2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter input size:");
int size = Integer.parseInt(scan.nextLine());
int[] arr = randomArray(size);
System.out.println("===================== Execution Time
====================");
long startTime = System.nanoTime();
heapSort(arr);
long endTime = System.nanoTime();
System.out.println("hw5.Heap Sort: " + (float) ((endTime - startTime) / 1000000) + "
milliseconds");
startTime = System.nanoTime();
mergeSort(arr, 0, arr.length - 1);
endTime = System.nanoTime();
System.out.println("Merge Sort: " + (float) ((endTime - startTime) / 1000000) + "
milliseconds");
startTime = System.nanoTime();
quickSort(arr, 0, arr.length - 1);
endTime = System.nanoTime();
System.out.println("Quick Sort: " + (float) ((endTime - startTime) / 1000000) + "
milliseconds");
System.out.println("========================================================="
);
}
public static int[] heapSort(int originalArray[]) {
int[] arr = originalArray.clone();
int n = arr.length;
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i = n - 1; i > 0; i--) {
// Move current root to end
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
return arr;
}
// To heapify a subtree rooted with node i which is
// an index in arr[]. n is size of heap
private static void heapify(int arr[], int n, int i) {
int largest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
// If left child is larger than root
if (l < n && arr[l] > arr[largest])
largest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
// If largest is not root
if (largest != i) {
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
private static void merge(int arr[], int l, int m, int r) {
// Find sizes of two subarrays to be merged
int n1 = m - l + 1;
int n2 = r - m;
/* Create temp arrays */
int L[] = new int[n1];
int R[] = new int[n2];
/*Copy data to temp arrays*/
for (int i = 0; i < n1; ++i)
L[i] = arr[l + i];
for (int j = 0; j < n2; ++j)
R[j] = arr[m + 1 + j];
/* Merge the temp arrays */
// Initial indexes of first and second subarrays
int i = 0, j = 0;
// Initial index of merged subarry array
int k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
/* Copy remaining elements of L[] if any */
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
/* Copy remaining elements of R[] if any */
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
// Main function that sorts arr[l..r] using
// merge()
private static int[] mergeSort(int originalArr[], int l, int r) {
int arr[] = originalArr.clone();
if (l < r) {
// Find the middle point
int m = l + (r - l) / 2;
// Sort first and second halves
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
// Merge the sorted halves
merge(arr, l, m, r);
}
return arr;
}
// A utility function to swap two elements
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
private static int partition(int[] arr, int low, int high) {
// pivot
int pivot = arr[high];
// Index of smaller element and
// indicates the right position
// of pivot found so far
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
// If current element is smaller
// than the pivot
if (arr[j] < pivot) {
// Increment index of
// smaller element
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return (i + 1);
}
/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index
*/
private static void quickSort(int[] originalArr, int low, int high) {
int[] arr = originalArr.clone();
if (low < high) {
// pi is partitioning index, arr[p]
// is now at right place
int pi = partition(arr, low, high);
// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
// Function to print an array
private static void printArray(int[] arr, int size) {
for (int i = 0; i < size; i++)
System.out.print(arr[i] + " ");
System.out.println();
}
private static int[] randomArray(int size) {
int[] arr = new int[size];
Random rand = new Random();
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(Integer.MAX_VALUE);
}
return arr;
}
}