@Mark, here are the changes that I have made.
Its some ambiguous to use Comparator and Comparable, you can read this post and see the differences: What is the difference between compare() and compareTo()?
Your indexes were wrong, like 0 to 'Sort by last name' and 'exit'
The import is always before the class statement
There were some brackets missing
4.5 There were one main method in Heap and the other options in Assignment1 that I removed just to compile
I would advice you to use Generics to make this class, you can read more here: https://docs.oracle.com/javase/tutorial/java/generics/. In your Head.sort method, you definied it to receive a Comparable and you were passing a Comparable and a Comparator, like I said, its ambiguous. Its better to you pass a generic array (Like anything-> String[], int[], yourOwnClass[]) and provide a second argument: the Comparator! So, lets go back, changed to use generics and provide your Comparator! Now you are calling the method sort and saying to it what is the parameter to compare (Comparator). You can see the final result here:
import java.util.Scanner;
public class Assignment1 {
public static void main(String[] args) {
Contact[] contacts = {
new Contact("Collins", "Kelly", "Illinois", 26),
new Contact("Smith", "Brandon", "Michigan", 32),
new Contact("Jones", "Mark", "California", 29),
new Contact("McDowell", "Ryan", "Texas", 30),
new Contact("Thompson", "April", "New York", 35)
};
int input;
do {
Scanner in = new Scanner(System.in);
System.out.println("Sort by last name: [1]");
System.out.println("Sort by first name: [2]");
System.out.println("Sort by age: [3]");
System.out.println("Enter an option or 0 to end input: ");
input = in.nextInt();
if (input == 0) {
System.out.println("Exiting...");
System.exit(input);
} else if (input == 3) {
Heap.sort(contacts, new Contact.AgeComparator());
for (Contact contact : contacts) {
System.out.println(contact);
}
} else if (input > 3 || input < 0) {
System.out.println("Invalid entry");
}
} while (input != 0);
}
}
Contact class:
import java.util.Comparator;
public class Contact {
String lastName;
String firstName;
String homeState;
Integer age;
Contact(String lastName, String firstName, String homeState, Integer age) {
this.lastName = lastName;
this.firstName = firstName;
this.homeState = homeState;
this.age = age;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getHomeState() {
return homeState;
}
public void setHomeState(String homeState) {
this.homeState = homeState;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return String.format("%8s %8s %7s, %7d", this.lastName, this.firstName, this.homeState, this.age);
}
static class FirstNameComparator implements Comparator<Contact> {
public int compare(Contact a, Contact b) {
return a.firstName.compareToIgnoreCase(b.firstName);
}
}
static class LastNameComparator implements Comparator<Contact> {
public int compare(Contact a, Contact b) {
return a.lastName.compareToIgnoreCase(b.lastName);
}
}
static class AgeComparator implements Comparator<Contact> {
public int compare(Contact a, Contact b) {
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
}
}
Heap class
import java.util.Comparator;
public class Heap {
// This class should not be instantiated.
private Heap() { }
/**
* Rearranges the array in ascending order, using the natural order.
* @param pq the array to be sorted
*/
public static <T> void sort(T[] pq, Comparator<T> comparator) {
int n = pq.length;
for (int k = n/2; k >= 1; k--)
sink(pq, k, n, comparator);
while (n > 1) {
exch(pq, 1, n--);
sink(pq, 1, n, comparator);
}
}
private static <T> void sink(T[] pq, int k, int n, Comparator<T> comparator) {
while (2*k <= n) {
int j = 2*k;
if (j < n && less(pq, j, j+1, comparator)) j++;
if (!less(pq, k, j, comparator)) break;
exch(pq, k, j);
k = j;
}
}
private static <T> boolean less(T[] pq, int i, int j, Comparator<T> comparator) {
return comparator.compare(pq[i-1],pq[j-1]) < 0;
}
private static void exch(Object[] pq, int i, int j) {
Object swap = pq[i-1];
pq[i-1] = pq[j-1];
pq[j-1] = swap;
}
}
Merge
import java.util.Comparator;
public class Merge {
// This class should not be instantiated.
private Merge() {
}
// stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]
private static <T> void merge(T[] a, T[] aux, int lo, int mid, int hi, Comparator<T> comparator) {
// precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
assert isSorted(a, lo, mid, comparator);
assert isSorted(a, mid + 1, hi, comparator);
// copy to aux[]
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
// merge back to a[]
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
if (i > mid) a[k] = aux[j++];
else if (j > hi) a[k] = aux[i++];
else if (less(aux[j], aux[i], comparator)) a[k] = aux[j++];
else a[k] = aux[i++];
}
// postcondition: a[lo .. hi] is sorted
assert isSorted(a, lo, hi, comparator);
}
// mergesort a[lo..hi] using auxiliary array aux[lo..hi]
private static <T> void sort(T[] a, T[] aux, int lo, int hi, Comparator<T> comparator) {
if (hi <= lo) return;
int mid = lo + (hi - lo) / 2;
sort(a, aux, lo, mid, comparator);
sort(a, aux, mid + 1, hi, comparator);
merge(a, aux, lo, mid, hi, comparator);
}
/**
* Rearranges the array in ascending order, using the natural order.
*
* @param a the array to be sorted
*/
public static <T> void sort(T[] a, Comparator<T> comparator) {
T[] aux = (T[])new Object[a.length];
sort(a, aux, 0, a.length - 1, comparator);
assert isSorted(a, comparator);
}
// is v < w ?
private static <T> boolean less(T v, T w, Comparator<T> comparator) {
return comparator.compare(v,w) < 0;
}
private static <T> boolean isSorted(T[] a, Comparator<T> comparator) {
return isSorted(a, 0, a.length - 1, comparator);
}
private static <T> boolean isSorted(T[] a, int lo, int hi, Comparator<T> comparator) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i - 1], comparator)) return false;
return true;
}
}
Quick
import java.util.Comparator;
public class Quick {
// This class should not be instantiated.
private Quick() {
}
/**
* Rearranges the array in ascending order, using the natural order.
*
* @param a the array to be sorted
*/
public static <T> void sort(T[] a, Comparator<T> comparator) {
sort(a, 0, a.length - 1, comparator);
assert isSorted(a, comparator);
}
// quicksort the subarray from a[lo] to a[hi]
private static <T> void sort(T[] a, int lo, int hi, Comparator<T> comparator) {
if (hi <= lo) return;
int j = partition(a, lo, hi, comparator);
sort(a, lo, j - 1, comparator);
sort(a, j + 1, hi, comparator);
assert isSorted(a, lo, hi, comparator);
}
// partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]
// and return the index j.
private static <T> int partition(T[] a, int lo, int hi, Comparator<T> comparator) {
int i = lo;
int j = hi + 1;
T v = a[lo];
while (true) {
// find item on lo to swap
while (less(a[++i], v, comparator))
if (i == hi) break;
// find item on hi to swap
while (less(v, a[--j], comparator))
if (j == lo) break; // redundant since a[lo] acts as sentinel
// check if pointers cross
if (i >= j) break;
exch(a, i, j);
}
// put partitioning item v at a[j]
exch(a, lo, j);
// now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
return j;
}
/**
* Rearranges the array so that {@code a[k]} contains the kth smallest key;
* {@code a[0]} through {@code a[k-1]} are less than (or equal to) {@code a[k]}; and
* {@code a[k+1]} through {@code a[n-1]} are greater than (or equal to) {@code a[k]}.
*
* @param a the array
* @param k the rank of the key
* @return the key of rank {@code k}
*/
public static <T> T select(T[] a, int k, Comparator<T> comparator) {
if (k < 0 || k >= a.length) {
throw new IndexOutOfBoundsException("Selected element out of bounds");
}
int lo = 0, hi = a.length - 1;
while (hi > lo) {
int i = partition(a, lo, hi, comparator);
if (i > k) hi = i - 1;
else if (i < k) lo = i + 1;
else return a[i];
}
return a[lo];
}
// is v < w ?
private static <T> boolean less(T v, T w, Comparator<T> comparator) {
return comparator.compare(v, w) < 0;
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
private static <T> boolean isSorted(T[] a, Comparator<T> comparator) {
return isSorted(a, 0, a.length - 1, comparator);
}
private static <T> boolean isSorted(T[] a, int lo, int hi, Comparator<T> comparator) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i - 1], comparator)) return false;
return true;
}
}