在 Pivot 上对数组进行分区

Posted

技术标签:

【中文标题】在 Pivot 上对数组进行分区【英文标题】:Partitioning an array on a Pivot 【发布时间】:2012-01-23 00:19:31 【问题描述】:

我正在尝试编写一个简单的算法来围绕枢轴移动元素,使得枢轴左侧的元素小于枢轴,而枢轴右侧的元素大于它(快速排序中的相同步骤)。我已经编写了有效的代码,但之后我将算法更改为以下,但它不起作用。

算法的思路很简单。

有两个指针,一个在数组的开头,一个在数组的末尾。如果 i 指向的元素小于枢轴,则继续跳过它,直到找到更大的元素;并继续递减 j 直到我们找到一个大于较小元素的元素。 【是常用算法】

现在是代码

private  static void sortByPivot(int[] a)


    Random r = new Random();
    int index = r.nextInt(a.length);
    int pivot = a[index];

    System.out.println("pivot = " + pivot);

    int i =0 , j = a.length -1;

    while(true)
        

            while(a[i] <= pivot) i++;

            while( j >0 && a[j] >= pivot) j--;

            if(i <= j)
            
                break;
            
            else
                swap(a,i,j);
               

        

        swap(a,i,index); //swap the pivot and the i

交换例程:

private static void swap(int[] a, int i , int j)

    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;

当我使用以下数组运行它时

  int[] a = 46,3,8,4,2,6,244,76 

以及枢轴摘为4时 输出是

         4 3 8 46 2 6 244 76 

对于位于边缘的其他一些枢轴,我得到一个空指针异常。

实施中是否有任何缺陷。这个逻辑对我来说似乎是正确的。我已经尝试了很长时间,但我无法修复它。

【问题讨论】:

您是否尝试过在调试器中单步执行您的代码,并将它的功能与您的预期进行比较?行为在什么时候出现分歧? 【参考方案1】:

对于多年后来到这里的任何人,我认为问题在于这个条件应该是&gt;=

if(i <= j)

 break;

看起来代码在第一次迭代中打破了循环。

所有运行的是最后一个交换函数。

【讨论】:

【参考方案2】:

逻辑不正确。您刚刚编写了代码。只需花一点时间,在任何输入上干运行这个程序,你就会直接发现缺陷。

更好的方法是采用wikipedia 上描述的方法 这是在快速排序中使用的对数组进行分区的就地版本。希望它能解决你的问题。

【讨论】:

【参考方案3】:

检查此implementation。它的工作原理完全相同。试着比较一下,看看哪里出错了。

请注意,如果i &lt;= j,您应该交换a[i]a[j] 的值,并从循环中中断。你在 else 上做,这是错误的,因为如果 a[i] 大于枢轴并且a[j] 在你到达 if 时小于枢轴,那么如果i &lt;= j 应该交换它们。

【讨论】:

【参考方案4】:

如果您只是想对所有内容进行排序,(我知道您说的是“分区”,但如果对整个内容进行排序会不会有问题?)有内置的方法可以做到这一点

java.util.Arrays.sort(int[] a)
java.util.Arrays.sort(int[] a, int fromIndex, int toIndex)

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Arrays.html

如果您的要求是自己做(功课!)然后尝试上面的调试方法;把你的期望写在纸上,然后一步一步看会发生什么

【讨论】:

透视例程通常用作排序例程的一部分。所以用一个排序例程来实现它有点违背了这一点......

以上是关于在 Pivot 上对数组进行分区的主要内容,如果未能解决你的问题,请参考以下文章

15分钟写不出快速排序的不考虑?!

快速排序

在Linux 环境上对磁盘进行分区操作

JS数组

如何使快速排序递归?

快排之三路快排