在数据透视表上对数组进行分区

时间:2011-12-18 12:26:14

标签: java algorithm sorting partitioning quicksort

我正在尝试编写一个简单的算法来移动枢轴周围的元素,使得枢轴左侧的元素小于枢轴,并且枢轴右侧的元素大于它(快速排序中的相同步骤) )。我编写了可行的代码,但之后我将算法更改为以下内容,但它无效。

算法的想法很简单。

  

有两个指针,一个在数组的开头,另一个在数组的末尾。如果i指向的元素小于pivot,则继续跳过它直到找到更大的元素;并继续递减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 

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

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

3 个答案:

答案 0 :(得分:2)

检查implementation。它完全按照相同的原则工作。尝试比较,看看你哪里出错了。

请注意,如果a[i],您应该交换a[j]i <= j的值,并且还要从循环中断开。你是在else上做的,这是错误的,因为如果a[i]大于数据透视表,a[j]在到达if时小于数据枢轴,那么如果{{ {1}}。

答案 1 :(得分:0)

如果你只是试图对它进行排序,(我知道你说过“分区”,但是如果整个事情被排序会是一个问题吗?)有内置的方法

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

如果你的要求是自己做(做作业!),那么试试上面的调试方法;在纸上写下你的期望,然后完全逐步看看会发生什么

答案 2 :(得分:0)

逻辑不正确。你刚刚编写了代码。只需花一点时间,在任何输入上干运行此程序,您将直接找到该缺陷。

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

相关问题