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

Java快速排序如何将中间元素与pivot交换

潘胤
2023-03-14

我正在尝试使用Java实现快速排序算法。我创建了我的配分函数,如下所示:

int [] quickPartition(int[] array, int low, int high){

    int  pivot = array[low], end_mark = high, start_mark = 1, temp;

    while (start_mark != end_mark) {
        if (array[start_mark] > pivot) {
            while (end_mark != start_mark) {
                if (array[end_mark] < pivot) {
                    temp = array[end_mark];
                    array[end_mark] = array[start_mark];
                    array[start_mark] = temp;

                    break;
                }
                end_mark--;
            }
        }
        start_mark++;
    }

    return array;
}

array[low]是我的轴,end\u标记是数组的最后一个元素,start\u标记是轴后的第一个元素

第一个同时循环从开始循环到结束,寻找比支点大的下一个数字。当找到时,第二个循环从数组的末端开始,朝着开始寻找小于枢轴的下一个数字。如果满足这两个条件,就会发生交换。但是,如果这两个循环索引(starindex和endindex)相遇,则会退出而循环。

样本数组:[54,26,93,17,77,90,31,44,55,20]
返回:[54,26,20,17,44,31,90,77,55,93]

如您所见,相关元素已经分区。然而,最后一步涉及交换枢轴(54)和(31),以便所有大于54的元素都在右边,小于54的元素都在左边。如何交换31和54,但在这一点上(start_index==end_index),同时循环已经停止?请注意,如果您交换的同时循环之外的值31将丢失。

共有2个答案

邹嘉致
2023-03-14

我很感激你想从错误中学习,所以我不会给你答案,而是给你每次迭代的步骤。请注意,合并排序要求在每次迭代后至少有一个元素位于其正确的排序位置。

步骤1:如果您按升序排序,并且您的轴是第一个元素,那么您的第一个指针(例如,i)需要找到小于轴的元素(所有等于或大于轴的元素都应该位于轴的右侧)

STEP2:当你发现第一个元素小于支点(由i指向),你需要从i 1迭代到高(调用迭代器指针j),并用每个小于i的元素交换数组[i]。

STEP3:用i交换支点。

在step3(一次迭代)的末尾,之前由i指向的元素(现在由枢轴指向)处于正确的排序位置。在这种情况下,枢轴将位于索引0处,其中包含数组的最少元素。

重复这些步骤,即再次调用快速分区函数,但现在为low=1

您的代码的问题是您从未交换过枢轴。此外,您永远不会试图找到比轴大的最小元素,这就是步骤2所做的。只需找到一个大于轴的元素

胡景焕
2023-03-14

在外部while循环结束时,array[start_mark]将是第一个数字

此外,如果轴是数组中的最小值,则此代码将生成ArrayOutOfBoundsException:end_标记将减小,直到end_标记==start_标记==1。然后start_标记将变为2,并且外部while循环条件将不满足。将外部while循环的条件设置为start_标记

int  pivot = array[low], end_mark = high, start_mark = 1, temp;
while (start_mark < end_mark) {
    if (array[start_mark] > pivot) {
        while (end_mark != start_mark) {
            if (array[end_mark] < pivot) {
                temp = array[end_mark];
                array[end_mark] = array[start_mark];
                array[start_mark] = temp;

                break;
            }
            end_mark--;
        }
    }
    start_mark++;
}
temp = array[start_mark-1];
array[start_mark-1] = pivot;
array[low] = temp;
return array;
 类似资料:
  • 我正在复习快速排序的实现(来自CLRS第3版)。我发现数组的递归除法从低索引到中1,然后从中1到高。 合并排序的实现如下所示: 由于它们都使用相同的除法策略,为什么快速排序忽略中间元素从到和到没有包含,而mergesort包含?

  • 我知道这听起来很奇怪,但是,我正在开发一个应用程序,当quicksort完成对数组的排序时,我必须执行一些操作,我需要找到起始索引、结束索引或透视之间的任何关系,或者任何可以告诉我这将是对数组排序所需的最后一个分区/交换... 配分函数: 交换功能:

  • 快速排序(Quicksort)是对冒泡排序的一种改进,是一种排序执行效率很高的排序算法。 快速排序的基本思想是:通过一趟排序,将要排序的数据分隔成独立的两部分,其中一部分的所有数据比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此使整个数据变成有序序列。 具体做法是:假设要对某个数组进行排序,首先需要任意选取一个数据(通常选用第一个数据)作为

  • 我有一个关于计算时间复杂度的非常普遍的问题(大O符号)。当人们说QuickSort最差的时间复杂度是O(n^2)(每次都选择数组的第一个元素作为轴心,并且数组是反向排序的)时,他们考虑了哪个操作来获得O(n^2)?人们会计算if/else语句所做的比较吗?或者他们只计算其进行的互换的总数?一般来说,你如何知道计算大O符号需要计算哪些“步骤”。 我知道这是一个非常基本的问题,但我已经阅读了谷歌上几乎

  • 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两

  • 1. 前言 本节内容是排序算法系列之一:快速排序,主要讲解了快速排序的主体思路,选取了一个待排序的数字列表对快速排序算法进行了演示,给出了快速排序算法的 Java 代码实现,帮助大家可以更好地理解快速排序算法。 2. 什么是快速排序? 快速排序(Quick Sort),是计算机科学与技术领域中非常经典的一种排序算法,应用分治思想进行排序。 快速排序由于其时间复杂度优于大部分的排序算法,因而命名为快