Assignment Chef icon Assignment Chef
All English tutorials

Programming lesson

Mastering Sorting Algorithms for 2D Points: A COMS228 Homework Guide

Learn how to implement selection sort, insertion sort, merge sort, and quicksort for 2D integer points. This guide covers median coordinate point calculation, comparator usage, and performance analysis.

COMS228 homework 2 sorting 2D points median coordinate point selection sort Java insertion sort Java merge sort Java quicksort Java sorting algorithms tutorial Java sorting comparator AbstractSorter implementation PointScanner class CompareSorters sorting performance analysis Java sorting algorithms comparison 2D integer points sorting COMS228 homework help

Understanding the Median Coordinate Point Problem

In COMS228 Homework 2, you are tasked with finding the median coordinate point (MCP) from a set of 2D integer points. This involves sorting the points by their x-coordinates and y-coordinates separately, then taking the median of each. The MCP is not necessarily one of the input points; it's the point whose x-coordinate is the median of all x-coordinates and whose y-coordinate is the median of all y-coordinates. This problem tests your ability to implement and compare four fundamental sorting algorithms: selection sort, insertion sort, merge sort, and quicksort.

Why Sorting Algorithms Matter

Sorting is a cornerstone of computer science, used in everything from organizing data in databases to optimizing search algorithms. In this assignment, you'll see how different sorting algorithms perform on small to medium-sized datasets (up to 10,201 points). The insights you gain will help you choose the right algorithm for real-world applications, such as sorting leaderboards in gaming, ranking search results, or organizing financial transactions.

Setting Up the Point Class

The Point class implements the Comparable interface. Its compareTo() method compares points first by x-coordinate, then by y-coordinate. This is crucial for sorting by either coordinate using the same comparator logic.

public class Point implements Comparable<Point> {
    private int x, y;
    public Point(int x, int y) { this.x = x; this.y = y; }
    public int compareTo(Point other) {
        if (this.x != other.x) return Integer.compare(this.x, other.x);
        return Integer.compare(this.y, other.y);
    }
}

The AbstractSorter Hierarchy

You'll create an abstract class AbstractSorter that stores the array of points and provides the sorting framework. Four subclasses implement the specific algorithms: SelectionSorter, InsertionSorter, MergeSorter, and QuickSorter. Each subclass must call the superclass constructor and implement the sort() method.

Implementing the Constructor

The constructor copies the input array to avoid modifying the original. It throws IllegalArgumentException if the array is null or empty.

protected AbstractSorter(Point[] pts) throws IllegalArgumentException {
    if (pts == null || pts.length == 0) throw new IllegalArgumentException();
    points = new Point[pts.length];
    System.arraycopy(pts, 0, points, 0, pts.length);
}

Comparator and Sorting by Coordinate

The setComparator() method sets a comparator that compares points by x or y. You can use a lambda or anonymous class.

public void setComparator(int coordinate) {
    if (coordinate == 0) // x
        pointComparator = (p1, p2) -> Integer.compare(p1.getX(), p2.getX());
    else // y
        pointComparator = (p1, p2) -> Integer.compare(p1.getY(), p2.getY());
}

Implementing the Four Sorting Algorithms

Selection Sort

Selection sort repeatedly finds the minimum element and swaps it into place. It's simple but O(n²), making it slow for large datasets.

public void sort() {
    for (int i = 0; i < points.length - 1; i++) {
        int minIdx = i;
        for (int j = i + 1; j < points.length; j++) {
            if (pointComparator.compare(points[j], points[minIdx]) < 0)
                minIdx = j;
        }
        swap(i, minIdx);
    }
}

Insertion Sort

Insertion sort builds the sorted array one element at a time by inserting each element into its correct position. It's also O(n²) but performs well on nearly sorted data.

public void sort() {
    for (int i = 1; i < points.length; i++) {
        Point key = points[i];
        int j = i - 1;
        while (j >= 0 && pointComparator.compare(points[j], key) > 0) {
            points[j + 1] = points[j];
            j--;
        }
        points[j + 1] = key;
    }
}

Merge Sort

Merge sort is a divide-and-conquer algorithm that splits the array, sorts each half recursively, and merges them. It's O(n log n) and stable.

private void mergeSort(Point[] arr, int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

Quicksort

Quicksort picks a pivot and partitions the array into elements less than and greater than the pivot. Average O(n log n), but worst-case O(n²) if poorly implemented.

private void quickSort(Point[] arr, int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

The PointScanner Class

PointScanner reads points from an array or file and performs two rounds of sorting to find the MCP. It measures the total sorting time in nanoseconds.

public void scan() {
    // Sort by x
    sorter.setComparator(0);
    long start = System.nanoTime();
    sorter.sort();
    long end = System.nanoTime();
    scanTime += end - start;
    medianX = sorter.getMedian().getX();

    // Sort by y
    sorter.setComparator(1);
    start = System.nanoTime();
    sorter.sort();
    end = System.nanoTime();
    scanTime += end - start;
    medianY = sorter.getMedian().getY();

    medianCoordinatePoint = new Point(medianX, medianY);
}

Comparing Sorting Algorithms with CompareSorters

The CompareSorters class runs all four algorithms on the same dataset and prints statistics. This allows you to see which algorithm is fastest for different input sizes and distributions.

public static void main(String[] args) {
    // Generate random points
    Point[] pts = generateRandomPoints(1000);
    
    // Create scanners with different algorithms
    PointScanner scSel = new PointScanner(pts, Algorithm.SelectionSort);
    PointScanner scIns = new PointScanner(pts, Algorithm.InsertionSort);
    PointScanner scMer = new PointScanner(pts, Algorithm.MergeSort);
    PointScanner scQuc = new PointScanner(pts, Algorithm.QuickSort);
    
    // Scan each
    scSel.scan();
    scIns.scan();
    scMer.scan();
    scQuc.scan();
    
    // Print stats
    System.out.println(scSel.stats());
    System.out.println(scIns.stats());
    System.out.println(scMer.stats());
    System.out.println(scQuc.stats());
}

Performance Analysis and Trends

In practice, merge sort and quicksort outperform selection and insertion sort for larger datasets. For example, sorting 10,000 points (the maximum allowed) will show significant time differences. This mirrors real-world scenarios: imagine sorting a leaderboard for a popular video game like Fortnite or Valorant – efficient sorting ensures fast updates. Similarly, financial apps like Robinhood sort stock data to display real-time rankings. Understanding these algorithms helps you build efficient systems.

Common Pitfalls and Tips

  • Null or empty input: Always check for null or empty arrays in constructors.
  • Comparator consistency: Ensure the comparator used in sorting matches the coordinate you intend to sort by.
  • Median index: Remember that the median index is points.length / 2 (integer division).
  • Duplicate points: The problem allows duplicates; your sorting must handle them correctly.
  • Timing precision: Use System.nanoTime() for accurate measurements. Run multiple trials and average.

Extra Credit: Early Submission

You can earn up to 10% extra credit by submitting up to 10 days early. Start early to avoid last-minute stress and to have time for thorough testing.

Tip: Use the extra time to experiment with different input sizes and observe how the sorting algorithms scale. This will deepen your understanding and help you write a better report.

Conclusion

This homework gives you hands-on experience with four classic sorting algorithms. By implementing them for 2D points, you'll learn about comparator design, algorithm complexity, and performance measurement. These skills are directly applicable to coding interviews and real-world software development. Good luck!