当前位置: 首页 > 知识库问答 >
问题:

保持分区元素顺序的简单quicksort java实现

芮星海
2023-03-14

...我正在尝试写一个我能写的最简单/优雅的解决方案(更喜欢不创建新的数组/列表,旋转多个元素等),下面是我的...

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而不是2 3,因为我的算法没有保持左分区元素的顺序(即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}->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),而不是左分区...

共有1个答案

杜诚
2023-03-14

维基百科博士

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;
    }
}
 类似资料:
  • 问题内容: 我正在尝试创建一个OrderedDict对象,但我不会立即创建它,否则所有元素都会混乱。 这是我的工作: 元素不按我分配的顺序排列 docs.python.org没有示例,我无法弄清楚订单为何变得混乱。任何帮助是极大的赞赏。 问题答案: 您的问题是,您正在构造一个将初始数据提供给的-这 不会 存储任何订单,因此订单在到达之前就丢失了。 解决方案是从有序数据类型构建-最简单的是的: 值得

  • 问题内容: 我有一个哈希表。values()方法以与插入顺序不同的顺序返回值。如何获得与插入顺序相同的值?使用LinkedHashmap是一种替代方法,但不同步。 问题答案: 使用。 接口的哈希表和链表的实现,具有可预测的迭代顺序。此实现的不同之处在于,它维护一个遍历其所有条目的双向链接列表。此链表定义了迭代顺序,通常是将键插入映射中 的顺序 ( insert-order )。请注意,如果将密钥

  • 问题 怎样在一个序列上面保持元素顺序的同时消除重复的值? 解决方案 如果序列上的值都是 hashable 类型,那么可以很简单的利用集合或者生成器来解决这个问题。比如: def dedupe(items): seen = set() for item in items: if item not in seen: yield item

  • 我正在用JAXB在列表中解组元素序列,见下文。 XML文件 Java-代码 但是,我有点担心textPoint元素的固有顺序,因为它们在XML文件中的顺序很好,但是没有元素(例如ID),我可以通过对它们进行排序。尽管如此,它似乎可以按照与XML文件相同的顺序对它们进行解组,因此不必担心这一点吗?

  • 我想通过moding user_id来创建用户事件的N个分区N以便用户可以按照发送事件的顺序处理事件。 如果我曾经决定N不足以处理负载,并且希望分别增加分区和使用者的数量,那么在使用用户事件时,我必须做什么来保留事件顺序呢?

  • 问题内容: 考虑该示例,该示例输出一些设备类型统计信息。(“ DeviceType”是一个带有十几个值的枚举。) 什么是最简单,最优雅的方式按不同 的频率 打印不同的元素(最常见的类型在前)? 随着快速浏览一下界面,有一个为这个没有现成的方法,并没有番石榴的的实现(,,等)似乎自动保持要素频率有序无论是。 问题答案: 我刚刚将此功能添加到了Guava,有关Javadoc ,请参见此处。 编辑 :根