【问题标题】:What algorithm can I use to sort an array with the use pivots我可以使用什么算法对使用枢轴的数组进行排序
【发布时间】:2015-02-19 07:26:45
【问题描述】:

请允许我使用一个示例(在 Java 中)更具体。

假设你要对这个数组进行排序:

[10, 20, 30, 40, 50, 60, 70, 80, 90]

让我们假设枢轴是值 30。排序后它应该是这样的:

[40, 50, 60, 70, 80, 90, 30, 10, 20]

大于 30 的数字在 30 的左侧结束(但仍按从小到大排序),小于 30 的数字在 30 的右侧(但仍按从小到大排序)。

注意:假设数据集很大,不一定要这个精确的数组集。

现在这是我提出的算法(以伪代码形式):

1). Count how many values are more than 30, call this count value 'X'. Swap the value of 30 at index X.

2). Have 2 "movers" that start on both ends, each moving towards the pivot and determining which numbers should go on what side

3). Use bubble sort on both sides of the pivot to finish the algorithm.

现在,这是我自己算法的问题。在我进行冒泡排序之前,它是 O(n),这使得它成为 O(n^2)。

我的具体问题是:什么是更好的方法,并且仍然保持 O(n)?或者如果可能的话 O(log n) ?答案可以是伪代码,但您选择为答案编写代码,我更喜欢用 Java 编写。

注意:该数组是一个整数数组。都有独特的价值。

编辑:合并排序显然是比冒泡排序更好的解决方案。我的问题实际上是针对寻找 O(n) 或 O(log n) 解决方案。

【问题讨论】:

  • 获取 Donald E. Knuth 的书“计算机编程的艺术”,第 3 卷 - 排序和搜索。它会回答你所有的问题。

标签: java arrays algorithm sorting


【解决方案1】:

首先,如果您关心时间,为什么要使用冒泡排序?你可以做的第一件事是用Merge Sort之类的算法代替冒泡排序,它的复杂度是O(n log n)

现在我告诉你 不可能O(n)O(log n) 找到更好的解决方案,假设你找到O(n) 甚至O(log n) 算法解决方案。现在您可以使用O(n) 对每个数组进行排序!因为一开始你用O(n) 找到数组的最小值,然后将它用作枢轴,然后使用你的算法,现在你有一个排序数组,它的复杂度是O(n),这还不可能。有关O(n log n) 的更多信息,请查看What are the rules for the "Ω(n log n) barrier" for sorting algorithms?

你可以找到排序算法的java实现here

【讨论】:

  • 使用归并排序比冒泡排序好得多。事实上,我赞成使用合并排序,但我不记得为什么我选择了冒泡排序。但我的问题实际上是为了找出是否存在 O(n) 或 O(log n) 解决方案,如果有,那将是什么方法
  • @EbadSaghar 我知道你的问题的真正含义,第二段我试图回答你的问题,一句话是不可能的
  • 抱歉造成误会。我想这解决了我的问题
  • 如果数据是小范围内的整数,可以用 O(n) 排序。根据值的范围,计数排序会起作用。
  • @JerryJeremiah“假设数据集非常大”,我知道这一点,但这不是一个普遍的答案
【解决方案2】:

如果您想以最简单的方式进行操作,请先按自然顺序对数组进行排序,然后对其进行旋转。

public static void main(String[] args) {
    int pivotValue = 3;
    Integer[] array = { 6, 4, 7, 3, 9, 1, 2, 0, 5, 8 };
    System.out.println(java.util.Arrays.toString(array));

    java.util.Arrays.sort(array);
    int pivotIndex = java.util.Arrays.binarySearch(array, pivotValue);
    int pivotOffset = Math.abs(pivotIndex + 1);
    java.util.List<Integer> list = java.util.Arrays.asList(array);
    java.util.Collections.rotate(list, -pivotOffset);
    if (pivotIndex > 0) {
        list = list.subList(array.length - pivotOffset, array.length);
        java.util.Collections.rotate(list, 1);
    }
    System.out.println(java.util.Arrays.toString(array));
}

二分搜索是O(log n),但排序和旋转是O(n),所以总体复杂度是O(n log n)(根据@brimborium 进行更正)。

【讨论】:

  • 排序怎么可能是 O(log n) 你用的是什么排序算法?
  • 它是O(n log n)。但这是一个很好的方法 imo,因为它干净且可读。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2020-09-13
相关资源
最近更新 更多