Data Structures and Algorithms in Java
GitHubAuthor
  • Preface
    • Syllabus
    • Schedule
  • 0. Getting Started
    • 0.1. Environment Setup
    • 0.2. Quiz
  • 1. Java Essentials
    • 1.1. Abstraction
    • 1.2. Implementation
    • 1.3. Unit Testing
    • 1.4. Quiz
  • 2. Priority Queues
    • 2.1. Simple Priority Queues
    • 2.2. Binary Heap
    • 2.3. Unit Testing
    • 2.4. Benchmarking
    • 2.5. Quiz
  • 3. Sorting Algorithms
    • 3.1. Abstraction
    • 3.2. Comparison-based Sort
    • 3.3. Divide & Conquer Sort
    • 3.4. Distribution-based Sort
    • 3.5. Quiz
    • 3.6. Homework
  • 4. Binary Search Trees
    • 4.1. Binary Search Trees
    • 4.2. Balanced BST
    • 4.2. AVL Trees
    • 4.3. Red-Black Trees
    • 4.4. Quiz
  • 5. Tries
    • 5.1. Concept
    • 5.2. Implementation
    • 5.3. Quiz
    • 5.4. Homework
  • 6. Disjoint Sets
    • 6.1. Concept
    • 6.2. Implementation
    • 6.3. Quiz
  • 7. Graphs
    • 7.1. Implementation
    • 7.2. Cycle Detection
    • 7.3. Topological Sorting
    • 7.4. Quiz
  • 8. Minimum Spanning Trees
    • 8.1. Abstraction
    • 8.2. Prim's Algorithm
    • 8.3. Kruskal’s Algorithm
    • 8.4. Edmonds' Algorithm
    • 8.5. Quiz
    • 8.6. Homework
  • 9. Network Flow
    • 9.1. Flow Network
    • 9.2. Ford-Fulkerson Algorithm
    • 9.3. Simplex Algorithm
    • 9.3. Quiz
  • 10. Dynamic Programming
    • 10.1. Fibonacci Sequence
    • 10.2. Tower of Hanoi
    • 10.3. Longest Common Subsequence
    • 10.4. Quiz
Powered by GitBook

©2023 Emory University - All rights reserved

On this page

Was this helpful?

Export as PDF
  1. 3. Sorting Algorithms

3.1. Abstraction

The abstract class for all sorting algorithms.

Previous3. Sorting AlgorithmsNext3.2. Comparison-based Sort

Last updated 2 years ago

Was this helpful?

Abstract Sort

Let us create an abstract class :

public abstract class AbstractSort<T extends Comparable<T>> {
    private final Comparator<T> comparator;
    protected long comparisons;
    protected long assignments;

    /** @param comparator specifies the precedence of comparable keys. */
    public AbstractSort(Comparator<T> comparator) {
        this.comparator = comparator;
        resetCounts();
    }

    /** @return the total number of comparisons performed during sort. */
    public long getComparisonCount() {
        return comparisons;
    }

    /** @return the total number of assignments performed during sort. */
    public long getAssignmentCount() {
        return assignments;
    }

    public void resetCounts() {
        comparisons = assignments = 0;
    }
}
  • L2-4: member fields:

    • comparator: specifies the precedence of comparable keys.

    • comparisons: counts the number of comparisons performed during sorting.

    • assignments: counts the number of assignments performed during sorting.

The two-member fields, comparisons and assignments, are used to micro-benchmark sorting algorithms inheriting AbstractSort.

Let us define three helper methods, compareTo(), assign(), and swap():

/**
 * @param array an array of comparable keys.
 * @param i     the index of the first key.
 * @param j     the index of the second key.
 * @return array[i].compareTo(array[j]).
 */
protected int compareTo(T[] array, int i, int j) {
    comparisons++;
    return comparator.compare(array[i], array[j]);
}

/**
 * array[index] = value.
 * @param array an array of comparable keys.
 * @param index the index of the array to assign.
 * @param value the value to be assigned.
 */
protected void assign(T[] array, int index, T value) {
    assignments++;
    array[index] = value;
}

/**
 * Swaps array[i] and array[j].
 * @param array an array of comparable keys.
 * @param i     the index of the first key.
 * @param j     the index of the second key.
 */
protected void swap(T[] array, int i, int j) {
    T t = array[i];
    assign(array, i, array[j]);
    assign(array, j, t);
}
  • L7: compares two keys in the array and increments the count.

  • L18: assigns the value to the specific position in the array and increments the count.

  • L29: swaps the values of the specific positions in the array by calling the assign() method.

These helper methods allow us to analyze the exact counts of those operations performed by different sorting algorithms.

How is it different to benchmark runtime speeds from counting these two operations?

Finally, let us define the default sort() that calls an overwritten abstract method, sort():

/**
 * Sorts the array in ascending order.
 * @param array an array of comparable keys.
 */
public void sort(T[] array) {
   sort(array, 0, array.length);
}

/**
 * Sorts the array[beginIndex:endIndex].
 * @param array      an array of comparable keys.
 * @param beginIndex the index of the first key to be sorted (inclusive).
 * @param endIndex   the index of the last key to be sorted (exclusive).
 */
abstract public void sort(T[] array, int beginIndex, int endIndex);
  • L5: calls the abstract method sort() that overwrites it.

  • L15: sorts the array in the range of (beginIndex, endIndex) as specified in comparator.

When would it be useful to sort a specific range in the input array?

AbstractSort