保持分区元素顺序的简单快速排序 java 实现
Simple quicksort java implementation while maintaining partition element order
TL;DR 维护左右分区顺序的最简单方法是什么?
所以...
我正在应对 this HackerRank 挑战,但由于挑战状态,我无法满足他们的打印要求...
Please maintain the original order of the elements in the left and right partitions while partitioning around a pivot element.
...我正在尝试编写最简单/优雅的解决方案(不希望创建新数组/列表、旋转多个元素等),这就是我所拥有的...
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
final int n;
final int[] arr;
try(final Scanner scanner = new Scanner(System.in)) {
n = scanner.nextInt();
arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
}
quickSort(arr, 0, n - 1);
}
private static void quickSort(final int[] arr, final int start, final int end) {
if(start >= end) return;
final int partitionIndex = partition(arr, start, end);
quickSort(arr, start, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, end);
for(int i = start; i <= end; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
private static int partition(final int[] arr, final int start, final int end) {
final int pivot = arr[start];
int pivotIndex = end + 1;
for(int i = end; i > start; i--) {
if(arr[i] > pivot) {
pivotIndex--;
final int temp = arr[pivotIndex];
arr[pivotIndex] = arr[i];
arr[i] = temp;
}
}
pivotIndex--;
arr[start] = arr[pivotIndex];
arr[pivotIndex] = pivot;
return pivotIndex;
}
}
...我的提交失败,因为我的第一个分区不是 {1, 3, 2, 5, 8, 7, 9}
而是 {3, 2, 1, 5, 8, 7, 9}
,因此在后续分区中,我的第一个合并是 1 2
而不是 [=15] =] 因为我的算法没有保持左分区的元素有序(即 1, 3, 2
)。
我的算法从末尾迭代到开头,不包括起始元素(基准)...
{5, 8, 1, 3, 7, 9, 2}
-> 枢轴为 5,枢轴索引为 7(越界)
{5, 8, 1, 3, 7, 9, 2}
-> 2不大于5,跳过
{5, 8, 1, 3, 7, 9, 2}
-> 9 大于 5,枢轴索引为 6,交换 9 和 2
{5, 8, 1, 3, 7, 2, 9}
-> 7 大于 5,枢轴索引为 5,交换 7 和 2
{5, 8, 1, 3, 2, 7, 9}
-> 3不大于5,跳过
{5, 8, 1, 3, 2, 7, 9}
-> 1不大于5,跳过
{5, 8, 1, 3, 2, 7, 9}
-> 8 大于 5,枢轴索引为 4,交换 8 和 2
{5, 2, 1, 3, 8, 7, 9}
-> 枢轴索引为 3,交换 5 和 3
{3, 2, 1, 5, 8, 7, 9}
-> 第一个分区后的最终结果
...我维护了右分区的顺序(即 8 7 9
),但不是左分区...
TL;DR from Wikipedia
Efficient implementations of Quicksort are not a stable sort, meaning that the relative order of equal sort items is not preserved.
所以...
不幸的是,为了使我的 Quicksort 实现稳定,我不得不做出让步;如果有人感兴趣,这就是我决定做的事情(选择简单而不是性能)...
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
final int n;
final int[] arr;
try(final Scanner scanner = new Scanner(System.in)) {
n = scanner.nextInt();
arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
}
quickSort(arr, 0, n - 1);
}
private static void quickSort(final int[] arr, final int start, final int end) {
if(start >= end) return;
final int partitionIndex = partition(arr, start, end);
quickSort(arr, start, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, end);
for(int i = start; i <= end; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
private static int partition(final int[] arr, final int start, final int end) {
final int pivot = arr[start];
int pivotIndex = start;
for(int i = start + 1; i <= end; i++) {
if(arr[i] < pivot) {
pivotIndex++;
}
}
int smallerIndex = start;
int biggerIndex = pivotIndex + 1;
final int[] copy = Arrays.copyOf(arr, arr.length);
for(int i = start + 1; i <= end; i++) {
if(copy[i] < pivot) {
arr[smallerIndex++] = copy[i];
} else if(arr[i] > pivot) {
arr[biggerIndex++] = copy[i];
}
}
arr[pivotIndex] = pivot;
return pivotIndex;
}
}
TL;DR 维护左右分区顺序的最简单方法是什么?
所以...
我正在应对 this HackerRank 挑战,但由于挑战状态,我无法满足他们的打印要求...
Please maintain the original order of the elements in the left and right partitions while partitioning around a pivot element.
...我正在尝试编写最简单/优雅的解决方案(不希望创建新数组/列表、旋转多个元素等),这就是我所拥有的...
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
final int n;
final int[] arr;
try(final Scanner scanner = new Scanner(System.in)) {
n = scanner.nextInt();
arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
}
quickSort(arr, 0, n - 1);
}
private static void quickSort(final int[] arr, final int start, final int end) {
if(start >= end) return;
final int partitionIndex = partition(arr, start, end);
quickSort(arr, start, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, end);
for(int i = start; i <= end; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
private static int partition(final int[] arr, final int start, final int end) {
final int pivot = arr[start];
int pivotIndex = end + 1;
for(int i = end; i > start; i--) {
if(arr[i] > pivot) {
pivotIndex--;
final int temp = arr[pivotIndex];
arr[pivotIndex] = arr[i];
arr[i] = temp;
}
}
pivotIndex--;
arr[start] = arr[pivotIndex];
arr[pivotIndex] = pivot;
return pivotIndex;
}
}
...我的提交失败,因为我的第一个分区不是 {1, 3, 2, 5, 8, 7, 9}
而是 {3, 2, 1, 5, 8, 7, 9}
,因此在后续分区中,我的第一个合并是 1 2
而不是 [=15] =] 因为我的算法没有保持左分区的元素有序(即 1, 3, 2
)。
我的算法从末尾迭代到开头,不包括起始元素(基准)...
{5, 8, 1, 3, 7, 9, 2}
-> 枢轴为 5,枢轴索引为 7(越界)
{5, 8, 1, 3, 7, 9, 2}
-> 2不大于5,跳过
{5, 8, 1, 3, 7, 9, 2}
-> 9 大于 5,枢轴索引为 6,交换 9 和 2
{5, 8, 1, 3, 7, 2, 9}
-> 7 大于 5,枢轴索引为 5,交换 7 和 2
{5, 8, 1, 3, 2, 7, 9}
-> 3不大于5,跳过
{5, 8, 1, 3, 2, 7, 9}
-> 1不大于5,跳过
{5, 8, 1, 3, 2, 7, 9}
-> 8 大于 5,枢轴索引为 4,交换 8 和 2
{5, 2, 1, 3, 8, 7, 9}
-> 枢轴索引为 3,交换 5 和 3
{3, 2, 1, 5, 8, 7, 9}
-> 第一个分区后的最终结果
...我维护了右分区的顺序(即 8 7 9
),但不是左分区...
TL;DR from Wikipedia
Efficient implementations of Quicksort are not a stable sort, meaning that the relative order of equal sort items is not preserved.
所以...
不幸的是,为了使我的 Quicksort 实现稳定,我不得不做出让步;如果有人感兴趣,这就是我决定做的事情(选择简单而不是性能)...
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
final int n;
final int[] arr;
try(final Scanner scanner = new Scanner(System.in)) {
n = scanner.nextInt();
arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
}
quickSort(arr, 0, n - 1);
}
private static void quickSort(final int[] arr, final int start, final int end) {
if(start >= end) return;
final int partitionIndex = partition(arr, start, end);
quickSort(arr, start, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, end);
for(int i = start; i <= end; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
private static int partition(final int[] arr, final int start, final int end) {
final int pivot = arr[start];
int pivotIndex = start;
for(int i = start + 1; i <= end; i++) {
if(arr[i] < pivot) {
pivotIndex++;
}
}
int smallerIndex = start;
int biggerIndex = pivotIndex + 1;
final int[] copy = Arrays.copyOf(arr, arr.length);
for(int i = start + 1; i <= end; i++) {
if(copy[i] < pivot) {
arr[smallerIndex++] = copy[i];
} else if(arr[i] > pivot) {
arr[biggerIndex++] = copy[i];
}
}
arr[pivotIndex] = pivot;
return pivotIndex;
}
}