From 70e29118523a7d7e483d59b1fbe94a45ae65cf1a Mon Sep 17 00:00:00 2001 From: Abhinav Sarkar Date: Mon, 8 Jul 2019 20:55:20 +0530 Subject: [PATCH] Adds quick select and quick top algos --- .../net/abhinavsarkar/algorist/Sorter.java | 24 +++++ .../algorist/sort/QuickSorter.java | 92 ++++++++++++++++--- 2 files changed, 101 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/abhinavsarkar/algorist/Sorter.java b/src/main/java/net/abhinavsarkar/algorist/Sorter.java index dd56c70..8a223d7 100644 --- a/src/main/java/net/abhinavsarkar/algorist/Sorter.java +++ b/src/main/java/net/abhinavsarkar/algorist/Sorter.java @@ -4,6 +4,30 @@ public interface Sorter { T[] sort(T[] input, Comparator comparator); + default T select(T[] input, int rank, Comparator comparator) { + if (rank < 1) { + throw new IllegalArgumentException("rank is less than one"); + } + if (rank > input.length) { + throw new IllegalArgumentException("rank is larger than input length"); + } + + T[] sorted = sort(input, comparator); + return sorted[rank - 1]; + } + + default T[] top(T[] input, int rank, Comparator comparator) { + if (rank < 1) { + throw new IllegalArgumentException("rank is less than one"); + } + if (rank > input.length) { + throw new IllegalArgumentException("rank is larger than input length"); + } + + return sort(input, comparator); + } + + @FunctionalInterface interface Comparator { int compare(T o1, T o2); diff --git a/src/main/java/net/abhinavsarkar/algorist/sort/QuickSorter.java b/src/main/java/net/abhinavsarkar/algorist/sort/QuickSorter.java index ddd2f87..1292740 100644 --- a/src/main/java/net/abhinavsarkar/algorist/sort/QuickSorter.java +++ b/src/main/java/net/abhinavsarkar/algorist/sort/QuickSorter.java @@ -6,7 +6,6 @@ import net.abhinavsarkar.algorist.Sorter; public class QuickSorter implements Sorter { - private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current(); @Override public T[] sort(T[] input, Comparator comparator) @@ -19,14 +18,6 @@ public class QuickSorter implements Sorter return sort(input, 0, input.length, comparator); } - private void shuffle(T[] input) - { - for (int i = input.length - 1; i > 0; i--) { - int j = RANDOM.nextInt(i + 1); - swap(input, i, j); - } - } - private T[] sort(T[] input, int start, int end, Comparator comparator) { if (end - start <= 1) { @@ -39,6 +30,76 @@ public class QuickSorter implements Sorter return input; } + @Override + public T[] top(T[] input, int rank, Comparator comparator) + { + checkRank(input, rank); + + shuffle(input); + return top(input, rank - 1, 0, input.length, comparator); + } + + private T[] top(T[] input, int rank, int start, int end, Comparator comparator) + { + if (end - start <= 1) { + return input; + } + + int pivot = partition(input, start, end, comparator); + sort(input, start, pivot, comparator); + if (pivot <= rank) + { + top(input, rank, pivot, end, comparator); + } + return input; + } + + @Override + public T select(T[] input, int rank, Comparator comparator) + { + checkRank(input, rank); + + shuffle(input); + return select(input, rank - 1, 0, input.length, comparator); + } + + public void checkRank(T[] input, int rank) + { + if (rank < 1) { + throw new IllegalArgumentException("rank is less than one"); + } + if (rank > input.length) { + throw new IllegalArgumentException("rank is larger than input length"); + } + } + + private T select(T[] input, int rank, int start, int end, Comparator comparator) + { + if (end - start == 1) { + if (rank == start) { + return input[start]; + } + throw new IllegalStateException("Impossible"); + } + + int pivot = partition(input, start, end, comparator); + if (pivot == rank) { + return input[pivot]; + } else if (pivot > rank) { + return select(input, rank, start, pivot, comparator); + } else { + return select(input, rank, pivot, end, comparator); + } + } + + private void shuffle(T[] input) + { + for (int i = input.length - 1; i > 0; i--) { + int j = ThreadLocalRandom.current().nextInt(i + 1); + swap(input, i, j); + } + } + private int partition(T[] input, int start, int end, Comparator comparator) { int pivot = end - 1; @@ -68,12 +129,13 @@ public class QuickSorter implements Sorter public static void main(String[] args) { Sorter sorter = new QuickSorter<>(); - String[] sorted = - sorter.sort(new String[]{ - "abhinav", "sarkar", "barista", "jordan", "data", - "cata", "meta", "dota", "best", "recursion"}, - (s, anotherString) -> anotherString.compareTo(s)); - System.out.println(Arrays.toString(sorted)); + String[] input = {"abhinav", "sarkar", "barista", "jordan", "data", "cata", + "meta", "dota", "best", "recursion"}; + Comparator comparator = (s1, s2) -> s2.compareTo(s1); + + System.out.println(Arrays.toString(sorter.sort(input, comparator))); + System.out.println(sorter.select(input, 1, comparator)); + System.out.println(Arrays.toString(sorter.top(input, 3, comparator))); } }