Bubble Sort

Bubble Sort repeatedly compares elements which are next to each other and swaps them if they are in the wrong order. Eventually, after repeating this the largest elements will bubble to the end.

https://www.geeksforgeeks.org/bubble-sort/

public class BubbleSort {
    public static void main(String[] args) {
        int arr[] = {64, 34, 25, 12, 22, 11, 90};
        bubbleSort(arr);
        printArray(arr);
    }

    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]) {
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
    }

    static void printArray(int arr[]) {
        int n = arr.length;
        for (int i=0; i<n; ++i)
            System.out.print(arr[i] + " ");
        System.out.println();
    }
}

BubbleSort.main(new String[0]);

11 12 22 25 34 64 90 
import java.util.*;

public class BubbleSortGeneric {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(64, 34, 25, 12, 22, 11, 90);
        bubbleSort(list);
        System.out.println(list);
    }

    static <T extends Comparable<T>> void bubbleSort(List<T> list) {
        int n = list.size();
        for (int i = 0; i < n-1; i++)
            for (int j = 0; j < n-i-1; j++)
                if (list.get(j).compareTo(list.get(j+1)) > 0) {
                    Collections.swap(list, j, j+1);
                }
    }
}

BubbleSortGeneric.main(new String[0]);
[11, 12, 22, 25, 34, 64, 90]

Selection Sort

Selection Sort works by repeatedly selecting the smallest element from the unsorted part of the list and moving it to a sorted sub-array.

https://www.geeksforgeeks.org/selection-sort/

public class SelectionSort {
    public static void main(String[] args) {
        int arr[] = {64, 34, 25, 12, 22, 11, 90};
        selectionSort(arr);
        printArray(arr);
    }

    static void selectionSort(int arr[]) {
        int n = arr.length;
        for (int i = 0; i < n-1; i++) {
            int min_idx = i;
            for (int j = i+1; j < n; j++)
                if (arr[j] < arr[min_idx])
                    min_idx = j;
            int temp = arr[min_idx];
            arr[min_idx] = arr[i];
            arr[i] = temp;
        }
    }

    static void printArray(int arr[]) {
        int n = arr.length;
        for (int i=0; i<n; ++i)
            System.out.print(arr[i] + " ");
        System.out.println();
    }
}

SelectionSort.main(new String[0]);
11 12 22 25 34 64 90 
import java.util.*;

public class SelectionSortGeneric<T extends Comparable<T>> {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(64, 34, 25, 12, 22, 11, 90);
        SelectionSortGeneric<Integer> sorter = new SelectionSortGeneric<>();
        sorter.selectionSort(list);
        System.out.println(list);
    }

    void selectionSort(List<T> list) {
        int n = list.size();
        for (int i = 0; i < n-1; i++) {
            int min_idx = i;
            for (int j = i+1; j < n; j++)
                if (list.get(j).compareTo(list.get(min_idx)) < 0)
                    min_idx = j;
            Collections.swap(list, min_idx, i);
        }
    }
}

SelectionSortGeneric.main(new String[0]);
[11, 12, 22, 25, 34, 64, 90]

Insertion Sort

Insertion Sort works by iteratively inserting each element of the list into its correct position, creating a sorted portion of the list as it goes.

https://www.geeksforgeeks.org/insertion-sort/

public class InsertionSort {
    public static void main(String[] args) {
        int arr[] = {64, 34, 25, 12, 22, 11, 90};
        insertionSort(arr);
        printArray(arr);
    }

    static void insertionSort(int arr[]) {
        int n = arr.length;
        for (int i = 1; i < n; ++i) {
            int key = arr[i];
            int j = i - 1;
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j = j - 1;
            }
            arr[j + 1] = key;
        }
    }

    static void printArray(int arr[]) {
        int n = arr.length;
        for (int i=0; i<n; ++i)
            System.out.print(arr[i] + " ");
        System.out.println();
    }
}
InsertionSort.main(new String[0]);
11 12 22 25 34 64 90 
import java.util.*;

public class InsertionSortGeneric<T extends Comparable<T>> {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(64, 34, 25, 12, 22, 11, 90);
        InsertionSortGeneric<Integer> sorter = new InsertionSortGeneric<>();
        sorter.insertionSort(list);
        System.out.println(list);
    }

    void insertionSort(List<T> list) {
        int n = list.size();
        for (int i = 1; i < n; ++i) {
            T key = list.get(i);
            int j = i - 1;
            while (j >= 0 && list.get(j).compareTo(key) > 0) {
                Collections.swap(list, j, j+1);
                j = j - 1;
            }
        }
    }
}
InsertionSortGeneric.main(new String[0]);

[11, 12, 22, 25, 34, 64, 90]

Merge Sort

Merge Sort uses divide-and-conquer by recursively breaking down a the list into two sub-lists until the sub-lists are all only 2 or 1 elements, at which point they are sorted and the β€˜merge’ method is used to combine the sorted sub-lists into one big sorted list.

https://www.geeksforgeeks.org/merge-sort/

public class MergeSort {
    public static void main(String[] args) {
        int arr[] = {64, 34, 25, 12, 22, 11, 90};
        sort(arr, 0, arr.length-1);
        printArray(arr);
    }

    static void merge(int arr[], int l, int m, int r) {
        int n1 = m - l + 1;
        int n2 = r - m;
        int L[] = new int[n1];
        int R[] = new int[n2];
        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];
        int i = 0, j = 0;
        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++;
        }
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    static void sort(int arr[], int l, int r) {
        if (l < r) {
            int m = (l+r)/2;
            sort(arr, l, m);
            sort(arr , m+1, r);
            merge(arr, l, m, r);
        }
    }

    static void printArray(int arr[]) {
        int n = arr.length;
        for (int i=0; i<n; ++i)
            System.out.print(arr[i] + " ");
        System.out.println();
    }
}
MergeSort.main(new String[0]);

11 12 22 25 34 64 90 
import java.util.*;

public class MergeSortGeneric<T extends Comparable<T>> {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(64, 34, 25, 12, 22, 11, 90);
        MergeSortGeneric<Integer> sorter = new MergeSortGeneric<>();
        sorter.mergeSort(list, 0, list.size() - 1);
        System.out.println(list);
    }

    void mergeSort(List<T> list, int start, int end) {
        if (start < end) {
            int middle = (start + end) / 2;
            mergeSort(list, start, middle);
            mergeSort(list, middle + 1, end);
            merge(list, start, middle, end);
        }
    }

    void merge(List<T> list, int start, int middle, int end) {
        List<T> leftList = new ArrayList<>(list.subList(start, middle + 1));
        List<T> rightList = new ArrayList<>(list.subList(middle + 1, end + 1));
        int leftIndex = 0, rightIndex = 0;
        for (int i = start; i <= end; i++) {
            if (rightIndex >= rightList.size() || (leftIndex < leftList.size() && leftList.get(leftIndex).compareTo(rightList.get(rightIndex)) <= 0)) {
                list.set(i, leftList.get(leftIndex++));
            } else {
                list.set(i, rightList.get(rightIndex++));
            }
        }
    }
}
MergeSortGeneric.main(new String[0]);

[11, 12, 22, 25, 34, 64, 90]

Quick Sort

Quick Sort is also a divide-and-conquer algorithm. It selects a pivot element from the array and partitions the other elements into two sub-arrays, depending on whether they are bigger or smaller than the pivot The sub-arrays are then recursively sorted.

public class QuickSort {
    public static void main(String[] args) {
        int arr[] = {64, 34, 25, 12, 22, 11, 90};
        sort(arr, 0, arr.length-1);
        printArray(arr);
    }

    static int partition(int arr[], int low, int high) {
        int pivot = arr[high]; 
        int i = (low-1);
        for (int j=low; j<high; j++) {
            if (arr[j] < pivot) {
                i++;
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        int temp = arr[i+1];
        arr[i+1] = arr[high];
        arr[high] = temp;
        return i+1;
    }

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

    static void printArray(int arr[]) {
        int n = arr.length;
        for (int i=0; i<n; ++i)
            System.out.print(arr[i] + " ");
        System.out.println();
    }
}
QuickSort.main(new String[0]);

11 12 22 25 34 64 90 
import java.util.*;

public class QuickSortGeneric<T extends Comparable<T>> {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(64, 34, 25, 12, 22, 11, 90);
        QuickSortGeneric<Integer> sorter = new QuickSortGeneric<>();
        sorter.quickSort(list, 0, list.size() - 1);
        System.out.println(list);
    }

    void quickSort(List<T> list, int start, int end) {
        if (start < end) {
            int pivotIndex = partition(list, start, end);
            quickSort(list, start, pivotIndex);
            quickSort(list, pivotIndex + 1, end);
        }
    }

    int partition(List<T> list, int start, int end) {
        T pivot = list.get((start + end) / 2);
        start--;
        end++;
        while (true) {
            do start++; while (list.get(start).compareTo(pivot) < 0);
            do end--; while (list.get(end).compareTo(pivot) > 0);
            if (start >= end) return end;
            Collections.swap(list, start, end);
        }
    }
}
QuickSortGeneric.main(new String[0]);

[11, 12, 22, 25, 34, 64, 90]

Learn Algorithmic Sort in depth

Pool Noodle Class

import java.util.HashMap;
import java.util.Map;

public class PoolNoodle implements Comparable<PoolNoodle> {
    private double length;
    private String color;

    private static final Map<String, String> colorEmojis = new HashMap<>();

    static {
        colorEmojis.put("red", "\uD83D\uDFE5");
        colorEmojis.put("blue", "\uD83D\uDFE6");
        colorEmojis.put("green", "\uD83D\uDFE9");
        colorEmojis.put("yellow", "\uD83D\uDFE8");
        colorEmojis.put("purple", "\uD83D\uDFEA");
        colorEmojis.put("orange", "\uD83D\uDFE7");
        colorEmojis.put("pink", "\uD83D\uDFEA");
        colorEmojis.put("brown", "\uD83D\uDFEB");
        colorEmojis.put("black", "\uD83D\uDFE4");
        colorEmojis.put("white", "\uD83D\uDFE3");
        colorEmojis.put("cyan", "\uD83D\uDFE1");
        colorEmojis.put("magenta", "\uD83D\uDFE3");
        colorEmojis.put("lime", "\uD83D\uDFE2");
    }

    public PoolNoodle() {
        this.length = 0.0;
        this.color = "unknown";
    }

    public PoolNoodle(double length, String color) {
        this.length = length;
        this.color = color;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "{ \"length\": " + length + ", \"color\": \"" + color + "\" }";
    }

    @Override
    public int compareTo(PoolNoodle other) {
        return Double.compare(this.length, other.length);
    }

    public String getColorEmoji() {
        return colorEmojis.getOrDefault(color, "❓");
    }

    public static String getColorLegend() {
        StringBuilder legend = new StringBuilder("Color Legend:\n");
        for (Map.Entry<String, String> entry : colorEmojis.entrySet()) {
            legend.append(entry.getValue()).append(" = ").append(entry.getKey()).append("\n");
        }
        return legend.toString();
    }
}

##

import java.util.ArrayList;
import java.util.List;

public class Beach {
    private List<PoolNoodle> poolNoodles;
    private String sortKey;

    public Beach() {
        this(true);
    }

    public Beach(boolean initialize) {
        poolNoodles = new ArrayList<>();
        if (initialize) {
            poolNoodles.add(new PoolNoodle(5.0, "red"));
            poolNoodles.add(new PoolNoodle(6.5, "blue"));
            poolNoodles.add(new PoolNoodle(4.3, "green"));
            poolNoodles.add(new PoolNoodle(7.1, "yellow"));
            poolNoodles.add(new PoolNoodle(3.8, "purple"));
            poolNoodles.add(new PoolNoodle(5.5, "orange"));
            poolNoodles.add(new PoolNoodle(6.2, "pink"));
            poolNoodles.add(new PoolNoodle(4.9, "brown"));
            poolNoodles.add(new PoolNoodle(7.5, "black"));
            poolNoodles.add(new PoolNoodle(4.0, "white"));
            poolNoodles.add(new PoolNoodle(5.8, "cyan"));
            poolNoodles.add(new PoolNoodle(6.8, "magenta"));
            poolNoodles.add(new PoolNoodle(3.5, "lime"));
        }
        sortKey = "length";
    }

    public void addPoolNoodle(PoolNoodle noodle) {
        poolNoodles.add(noodle);
    }

    public void setSortKey(String sortKey) {
        this.sortKey = sortKey;
    }

    public void sortPoolNoodles(boolean showVisualization) {
        for (int i = 0; i < poolNoodles.size() - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < poolNoodles.size(); j++) {
                if (compare(poolNoodles.get(j), poolNoodles.get(minIndex)) < 0) {
                    minIndex = j;
                }
            }
            PoolNoodle temp = poolNoodles.get(minIndex);
            poolNoodles.set(minIndex, poolNoodles.get(i));
            poolNoodles.set(i, temp);

            if (showVisualization) {
                System.out.println("Step " + (i + 1) + ":");
                visualizeStep();
            }
        }
    }

    private int compare(PoolNoodle n1, PoolNoodle n2) {
        switch (sortKey) {
            case "color":
                return n1.getColor().compareTo(n2.getColor());
            case "length":
            default:
                return Double.compare(n1.getLength(), n2.getLength());
        }
    }

    private void visualizeStep() {
        for (PoolNoodle noodle : poolNoodles) {
            int length = (int) Math.floor(noodle.getLength());
            for (int i = 0; i < length; i++) {
                System.out.print(noodle.getColorEmoji());
            }
            System.out.print(" ");
        }
        System.out.println();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{\n  \"poolNoodles\": [\n");
        for (int i = 0; i < poolNoodles.size(); i++) {
            sb.append("    ").append(poolNoodles.get(i).toString());
            if (i < poolNoodles.size() - 1) {
                sb.append(",");
            }
            sb.append("\n");
        }
        sb.append("  ]\n}");
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println(PoolNoodle.getColorLegend());

        Beach beach1 = new Beach();
        System.out.println("Before sorting beach1 by length:");
        System.out.println(beach1);
        beach1.setSortKey("length");
        beach1.sortPoolNoodles(true);
        System.out.println("After sorting beach1 by length:");
        System.out.println(beach1);

        Beach beach2 = new Beach(false);
        beach2.addPoolNoodle(new PoolNoodle(2.5, "red"));
        beach2.addPoolNoodle(new PoolNoodle(6.0, "blue"));
        beach2.addPoolNoodle(new PoolNoodle(1.5, "green"));
        beach2.addPoolNoodle(new PoolNoodle(7.3, "yellow"));
        beach2.addPoolNoodle(new PoolNoodle(4.0, "purple"));
        System.out.println("Before sorting beach2 by length:");
        System.out.println(beach2);
        beach2.setSortKey("length");
        beach2.sortPoolNoodles(true);
        System.out.println("After sorting beach2 by length:");
        System.out.println(beach2);

        Beach beach3 = new Beach(false);
        beach3.addPoolNoodle(new PoolNoodle(3.5, "red"));
        beach3.addPoolNoodle(new PoolNoodle(5.0, "blue"));
        beach3.addPoolNoodle(new PoolNoodle(2.2, "green"));
        beach3.addPoolNoodle(new PoolNoodle(6.1, "yellow"));
        beach3.addPoolNoodle(new PoolNoodle(4.8, "purple"));
        System.out.println("Before sorting beach3 by color:");
        System.out.println(beach3);
        beach3.setSortKey("color");
        beach3.sortPoolNoodles(true);
        System.out.println("After sorting beach3 by color:");
        System.out.println(beach3);
    }
}

Beach.main(new String[0]);
Color Legend:
🟣 = magenta
πŸŸͺ = pink
🟩 = green
🟒 = lime
🟨 = yellow
🟀 = black
🟫 = brown
🟑 = cyan
πŸŸ₯ = red
🟧 = orange
🟦 = blue
🟣 = white
πŸŸͺ = purple

Before sorting beach1 by length:
{
  "poolNoodles": [
    { "length": 5.0, "color": "red" },
    { "length": 6.5, "color": "blue" },
    { "length": 4.3, "color": "green" },
    { "length": 7.1, "color": "yellow" },
    { "length": 3.8, "color": "purple" },
    { "length": 5.5, "color": "orange" },
    { "length": 6.2, "color": "pink" },
    { "length": 4.9, "color": "brown" },
    { "length": 7.5, "color": "black" },
    { "length": 4.0, "color": "white" },
    { "length": 5.8, "color": "cyan" },
    { "length": 6.8, "color": "magenta" },
    { "length": 3.5, "color": "lime" }
  ]
}
Step 1:
🟒🟒🟒 🟦🟦🟦🟦🟦🟦 🟩🟩🟩🟩 🟨🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺ 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟫🟫🟫🟫 🟀🟀🟀🟀🟀🟀🟀 🟣🟣🟣🟣 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 2:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟩🟩🟩🟩 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟫🟫🟫🟫 🟀🟀🟀🟀🟀🟀🟀 🟣🟣🟣🟣 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 3:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟫🟫🟫🟫 🟀🟀🟀🟀🟀🟀🟀 🟩🟩🟩🟩 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 4:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟦🟦🟦🟦🟦🟦 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟫🟫🟫🟫 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 5:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 6:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 🟧🟧🟧🟧🟧 
Step 7:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟦🟦🟦🟦🟦🟦 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 8:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 🟣🟣🟣🟣🟣🟣 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 9:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 🟣🟣🟣🟣🟣🟣 🟀🟀🟀🟀🟀🟀🟀 
Step 10:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟨🟨🟨🟨🟨🟨🟨 🟣🟣🟣🟣🟣🟣 🟀🟀🟀🟀🟀🟀🟀 
Step 11:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟣🟣🟣🟣🟣🟣 🟨🟨🟨🟨🟨🟨🟨 🟀🟀🟀🟀🟀🟀🟀 
Step 12:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟣🟣🟣🟣🟣🟣 🟨🟨🟨🟨🟨🟨🟨 🟀🟀🟀🟀🟀🟀🟀 
After sorting beach1 by length:
{
  "poolNoodles": [
    { "length": 3.5, "color": "lime" },
    { "length": 3.8, "color": "purple" },
    { "length": 4.0, "color": "white" },
    { "length": 4.3, "color": "green" },
    { "length": 4.9, "color": "brown" },
    { "length": 5.0, "color": "red" },
    { "length": 5.5, "color": "orange" },
    { "length": 5.8, "color": "cyan" },
    { "length": 6.2, "color": "pink" },
    { "length": 6.5, "color": "blue" },
    { "length": 6.8, "color": "magenta" },
    { "length": 7.1, "color": "yellow" },
    { "length": 7.5, "color": "black" }
  ]
}
Before sorting beach2 by length:
{
  "poolNoodles": [
    { "length": 2.5, "color": "red" },
    { "length": 6.0, "color": "blue" },
    { "length": 1.5, "color": "green" },
    { "length": 7.3, "color": "yellow" },
    { "length": 4.0, "color": "purple" }
  ]
}
Step 1:
🟩 🟦🟦🟦🟦🟦🟦 πŸŸ₯πŸŸ₯ 🟨🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 2:
🟩 πŸŸ₯πŸŸ₯ 🟦🟦🟦🟦🟦🟦 🟨🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 3:
🟩 πŸŸ₯πŸŸ₯ πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 
Step 4:
🟩 πŸŸ₯πŸŸ₯ πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟨🟨🟨🟨🟨🟨🟨 
After sorting beach2 by length:
{
  "poolNoodles": [
    { "length": 1.5, "color": "green" },
    { "length": 2.5, "color": "red" },
    { "length": 4.0, "color": "purple" },
    { "length": 6.0, "color": "blue" },
    { "length": 7.3, "color": "yellow" }
  ]
}
Before sorting beach3 by color:
{
  "poolNoodles": [
    { "length": 3.5, "color": "red" },
    { "length": 5.0, "color": "blue" },
    { "length": 2.2, "color": "green" },
    { "length": 6.1, "color": "yellow" },
    { "length": 4.8, "color": "purple" }
  ]
}
Step 1:
🟦🟦🟦🟦🟦 πŸŸ₯πŸŸ₯πŸŸ₯ 🟩🟩 🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 2:
🟦🟦🟦🟦🟦 🟩🟩 πŸŸ₯πŸŸ₯πŸŸ₯ 🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 3:
🟦🟦🟦🟦🟦 🟩🟩 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟨🟨🟨🟨🟨🟨 πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 4:
🟦🟦🟦🟦🟦 🟩🟩 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ πŸŸ₯πŸŸ₯πŸŸ₯ 🟨🟨🟨🟨🟨🟨 
After sorting beach3 by color:
{
  "poolNoodles": [
    { "length": 5.0, "color": "blue" },
    { "length": 2.2, "color": "green" },
    { "length": 4.8, "color": "purple" },
    { "length": 3.5, "color": "red" },
    { "length": 6.1, "color": "yellow" }
  ]
}

With linked list

import java.util.LinkedList;
import java.util.List;

public class Beach {
    private LinkedList<PoolNoodle> poolNoodles;
    private String sortKey;

    public Beach() {
        this(true);
    }

    public Beach(boolean initialize) {
        poolNoodles = new LinkedList<>();
        if (initialize) {
            poolNoodles.add(new PoolNoodle(5.0, "red"));
            poolNoodles.add(new PoolNoodle(6.5, "blue"));
            poolNoodles.add(new PoolNoodle(4.3, "green"));
            poolNoodles.add(new PoolNoodle(7.1, "yellow"));
            poolNoodles.add(new PoolNoodle(3.8, "purple"));
            poolNoodles.add(new PoolNoodle(5.5, "orange"));
            poolNoodles.add(new PoolNoodle(6.2, "pink"));
            poolNoodles.add(new PoolNoodle(4.9, "brown"));
            poolNoodles.add(new PoolNoodle(7.5, "black"));
            poolNoodles.add(new PoolNoodle(4.0, "white"));
            poolNoodles.add(new PoolNoodle(5.8, "cyan"));
            poolNoodles.add(new PoolNoodle(6.8, "magenta"));
            poolNoodles.add(new PoolNoodle(3.5, "lime"));
        }
        sortKey = "length";
    }

    public void addPoolNoodle(PoolNoodle noodle) {
        poolNoodles.add(noodle);
    }

    public void setSortKey(String sortKey) {
        this.sortKey = sortKey;
    }

    public void sortPoolNoodles(boolean showVisualization) {
        for (int i = 0; i < poolNoodles.size() - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < poolNoodles.size(); j++) {
                if (compare(poolNoodles.get(j), poolNoodles.get(minIndex)) < 0) {
                    minIndex = j;
                }
            }
            PoolNoodle temp = poolNoodles.get(minIndex);
            poolNoodles.set(minIndex, poolNoodles.get(i));
            poolNoodles.set(i, temp);

            if (showVisualization) {
                System.out.println("Step " + (i + 1) + ":");
                visualizeStep();
            }
        }
    }

    private int compare(PoolNoodle n1, PoolNoodle n2) {
        switch (sortKey) {
            case "color":
                return n1.getColor().compareTo(n2.getColor());
            case "length":
            default:
                return Double.compare(n1.getLength(), n2.getLength());
        }
    }

    private void visualizeStep() {
        for (PoolNoodle noodle : poolNoodles) {
            int length = (int) Math.floor(noodle.getLength());
            for (int i = 0; i < length; i++) {
                System.out.print(noodle.getColorEmoji());
            }
            System.out.print(" ");
        }
        System.out.println();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{\n  \"poolNoodles\": [\n");
        for (int i = 0; i < poolNoodles.size(); i++) {
            sb.append("    ").append(poolNoodles.get(i).toString());
            if (i < poolNoodles.size() - 1) {
                sb.append(",");
            }
            sb.append("\n");
        }
        sb.append("  ]\n}");
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println(PoolNoodle.getColorLegend());

        Beach beach1 = new Beach();
        System.out.println("Before sorting beach1 by length:");
        System.out.println(beach1);
        beach1.setSortKey("length");
        beach1.sortPoolNoodles(true);
        System.out.println("After sorting beach1 by length:");
        System.out.println(beach1);

        Beach beach2 = new Beach(false);
        beach2.addPoolNoodle(new PoolNoodle(2.5, "red"));
        beach2.addPoolNoodle(new PoolNoodle(6.0, "blue"));
        beach2.addPoolNoodle(new PoolNoodle(1.5, "green"));
        beach2.addPoolNoodle(new PoolNoodle(7.3, "yellow"));
        beach2.addPoolNoodle(new PoolNoodle(4.0, "purple"));
        System.out.println("Before sorting beach2 by length:");
        System.out.println(beach2);
        beach2.setSortKey("length");
        beach2.sortPoolNoodles(true);
        System.out.println("After sorting beach2 by length:");
        System.out.println(beach2);

        Beach beach3 = new Beach(false);
        beach3.addPoolNoodle(new PoolNoodle(3.5, "red"));
        beach3.addPoolNoodle(new PoolNoodle(5.0, "blue"));
        beach3.addPoolNoodle(new PoolNoodle(2.2, "green"));
        beach3.addPoolNoodle(new PoolNoodle(6.1, "yellow"));
        beach3.addPoolNoodle(new PoolNoodle(4.8, "purple"));
        System.out.println("Before sorting beach3 by color:");
        System.out.println(beach3);
        beach3.setSortKey("color");
        beach3.sortPoolNoodles(true);
        System.out.println("After sorting beach3 by color:");
        System.out.println(beach3);
    }
}

Beach.main(new String[0]);
Color Legend:
🟣 = magenta
πŸŸͺ = pink
🟩 = green
🟒 = lime
🟨 = yellow
🟀 = black
🟫 = brown
🟑 = cyan
πŸŸ₯ = red
🟧 = orange
🟦 = blue
🟣 = white
πŸŸͺ = purple

Before sorting beach1 by length:
{
  "poolNoodles": [
    { "length": 5.0, "color": "red" },
    { "length": 6.5, "color": "blue" },
    { "length": 4.3, "color": "green" },
    { "length": 7.1, "color": "yellow" },
    { "length": 3.8, "color": "purple" },
    { "length": 5.5, "color": "orange" },
    { "length": 6.2, "color": "pink" },
    { "length": 4.9, "color": "brown" },
    { "length": 7.5, "color": "black" },
    { "length": 4.0, "color": "white" },
    { "length": 5.8, "color": "cyan" },
    { "length": 6.8, "color": "magenta" },
    { "length": 3.5, "color": "lime" }
  ]
}
Step 1:
🟒🟒🟒 🟦🟦🟦🟦🟦🟦 🟩🟩🟩🟩 🟨🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺ 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟫🟫🟫🟫 🟀🟀🟀🟀🟀🟀🟀 🟣🟣🟣🟣 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 2:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟩🟩🟩🟩 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟫🟫🟫🟫 🟀🟀🟀🟀🟀🟀🟀 🟣🟣🟣🟣 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 3:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟫🟫🟫🟫 🟀🟀🟀🟀🟀🟀🟀 🟩🟩🟩🟩 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 4:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟦🟦🟦🟦🟦🟦 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟫🟫🟫🟫 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 5:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 🟧🟧🟧🟧🟧 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 6:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 🟧🟧🟧🟧🟧 
Step 7:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟦🟦🟦🟦🟦🟦 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟑🟑🟑🟑🟑 🟣🟣🟣🟣🟣🟣 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 8:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 🟀🟀🟀🟀🟀🟀🟀 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 🟣🟣🟣🟣🟣🟣 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 9:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 🟣🟣🟣🟣🟣🟣 🟀🟀🟀🟀🟀🟀🟀 
Step 10:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟨🟨🟨🟨🟨🟨🟨 🟣🟣🟣🟣🟣🟣 🟀🟀🟀🟀🟀🟀🟀 
Step 11:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟣🟣🟣🟣🟣🟣 🟨🟨🟨🟨🟨🟨🟨 🟀🟀🟀🟀🟀🟀🟀 
Step 12:
🟒🟒🟒 πŸŸͺπŸŸͺπŸŸͺ 🟣🟣🟣🟣 🟩🟩🟩🟩 🟫🟫🟫🟫 πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ 🟧🟧🟧🟧🟧 🟑🟑🟑🟑🟑 πŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟣🟣🟣🟣🟣🟣 🟨🟨🟨🟨🟨🟨🟨 🟀🟀🟀🟀🟀🟀🟀 
After sorting beach1 by length:
{
  "poolNoodles": [
    { "length": 3.5, "color": "lime" },
    { "length": 3.8, "color": "purple" },
    { "length": 4.0, "color": "white" },
    { "length": 4.3, "color": "green" },
    { "length": 4.9, "color": "brown" },
    { "length": 5.0, "color": "red" },
    { "length": 5.5, "color": "orange" },
    { "length": 5.8, "color": "cyan" },
    { "length": 6.2, "color": "pink" },
    { "length": 6.5, "color": "blue" },
    { "length": 6.8, "color": "magenta" },
    { "length": 7.1, "color": "yellow" },
    { "length": 7.5, "color": "black" }
  ]
}
Before sorting beach2 by length:
{
  "poolNoodles": [
    { "length": 2.5, "color": "red" },
    { "length": 6.0, "color": "blue" },
    { "length": 1.5, "color": "green" },
    { "length": 7.3, "color": "yellow" },
    { "length": 4.0, "color": "purple" }
  ]
}
Step 1:
🟩 🟦🟦🟦🟦🟦🟦 πŸŸ₯πŸŸ₯ 🟨🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 2:
🟩 πŸŸ₯πŸŸ₯ 🟦🟦🟦🟦🟦🟦 🟨🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 3:
🟩 πŸŸ₯πŸŸ₯ πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟨🟨🟨🟨🟨🟨🟨 🟦🟦🟦🟦🟦🟦 
Step 4:
🟩 πŸŸ₯πŸŸ₯ πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟦🟦🟦🟦🟦🟦 🟨🟨🟨🟨🟨🟨🟨 
After sorting beach2 by length:
{
  "poolNoodles": [
    { "length": 1.5, "color": "green" },
    { "length": 2.5, "color": "red" },
    { "length": 4.0, "color": "purple" },
    { "length": 6.0, "color": "blue" },
    { "length": 7.3, "color": "yellow" }
  ]
}
Before sorting beach3 by color:
{
  "poolNoodles": [
    { "length": 3.5, "color": "red" },
    { "length": 5.0, "color": "blue" },
    { "length": 2.2, "color": "green" },
    { "length": 6.1, "color": "yellow" },
    { "length": 4.8, "color": "purple" }
  ]
}
Step 1:
🟦🟦🟦🟦🟦 πŸŸ₯πŸŸ₯πŸŸ₯ 🟩🟩 🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 2:
🟦🟦🟦🟦🟦 🟩🟩 πŸŸ₯πŸŸ₯πŸŸ₯ 🟨🟨🟨🟨🟨🟨 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 
Step 3:
🟦🟦🟦🟦🟦 🟩🟩 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ 🟨🟨🟨🟨🟨🟨 πŸŸ₯πŸŸ₯πŸŸ₯ 
Step 4:
🟦🟦🟦🟦🟦 🟩🟩 πŸŸͺπŸŸͺπŸŸͺπŸŸͺ πŸŸ₯πŸŸ₯πŸŸ₯ 🟨🟨🟨🟨🟨🟨 
After sorting beach3 by color:
{
  "poolNoodles": [
    { "length": 5.0, "color": "blue" },
    { "length": 2.2, "color": "green" },
    { "length": 4.8, "color": "purple" },
    { "length": 3.5, "color": "red" },
    { "length": 6.1, "color": "yellow" }
  ]
}