【问题标题】:Combine QuickSort and Median selection algorithm结合快速排序和中值选择算法
【发布时间】:2012-05-23 11:42:58
【问题描述】:

我想修改 QuickSort(在 Java 中),以便每次调用 Partition 时,都将比例数组的中值用作枢轴。

我在 Java 中有一个中值选择算法,它返回第 k 个最小的元素,在本例中为中值。我在java中有大量的快速排序算法,它们都可以自行工作并对数组进行排序。不幸的是,我无法将这两者结合起来以实现上述目标......每次我尝试它时,我通常都会遇到 stackoverflow 错误。

谁能给我看代码,看看怎么做?

谢谢

编辑:例如,这是我尝试使用的中值选择算法。

public int quickSelect(int[] A, int p, int r, int k) {
    if (p==r) return A[p];
    int q = Partition(A,p,r);
    int len = q-p+1;

    if (k == len) return A[q];
    else if (k<len) return Select(A,p,q-1,k);
    else return Select(A,q+1,r,k-len);
}

public int partition(int[]A, int p, int r) {
    int x = A[r];
    int i = p-1;
    for (int j = p; j<=r-1; j++) {
        if (A[j] <= x) {
            i++;
            swap(A,i,j);
        }
    }
    swap(A,i+1,r);
    return i+1;
}

它自己工作,但是当我尝试通过快速排序的分区函数调用 quickSelect 以返回要使用的枢轴时,它不起作用。显然我做错了什么,但我不知道是什么。不幸的是,在互联网上我没有找到任何算法,即使是伪代码,也可以将中值选择与快速排序结合起来。

【问题讨论】:

  • 查看您正在使用的代码会很有帮助。理想情况下只是相关位。
  • 有人吗?我没有意识到它是如此艰难......或者我不是很清楚我在寻找什么?

标签: java quicksort median


【解决方案1】:

获取中位数的标准方法是对数据进行排序。并且您想通过对中位数进行分区来对数据进行排序。这对我来说似乎是鸡和蛋。

您能否详细说明为什么要在中位数上进行分区/枢轴?

【讨论】:

  • 我知道我可以通过对数据进行排序来找到中位数,但这就是重点,我想在不这样做的情况下找到它。我希望每次调用快速排序的分区函数时都将中值用作枢轴,因为中值是理想的枢轴。
  • @user1397309 你没有回答这个问题——你为什么要那样做?您是否知道,通过做过多的工作(找到中值)来推动算法更有效(按中值划分)可能比(例如)随机划分要慢?
  • @FrantisekKossuth 是的,我知道你在说什么。我正在试验。
【解决方案2】:

您正在寻找的是选择算法。这是link with pseudocode。

来自链接:

在计算机科学中,选择算法是一种用于查找列表中第 k 个最小数字的算法

要找到中位数,您需要在列表中找到 k=floor((n+1)/2) 的最小数,其中 n 是列表的大小。

【讨论】:

  • 谢谢,我知道了。这就是我正在使用的(我认为)。我想把这个选择算法和快速排序结合起来,但是我做不到。
【解决方案3】:

请注意,在 PARTITION 中,pivot 是 A[r]。

public int QUICKSORT2(int[] A, int p, int r) {
    if (p<r) {
        int median=Math.floor((p + r) /2) - p + 1
        int q=SELECT(A, p, r, median)
        q=PARTITION2(A, p, r, q)
        QUICKSORT2(A, p, q-1)
        QUICKSORT2(A, q+1, r)
    }
}

public int PARTITION2(int[]A, int p, int r, int q) {
    int temp = A[r];
    A[r]=A[q];
    A[q]=temp;
    return PARTITION(A, p, r)
}

【讨论】:

    【解决方案4】:

    你可以用这个...

    int Select(int array[],int start, int end,int k){
    
    if(start==end){
        return start;
    }
    
    int x=array[end];
    int i=start-1;
    for(int j=start;j<=end-1;j++){
        if(array[j]<x){
            i++;
            Swap(array+i,array+j);
        }
    }
    i++;
    Swap(array+i,array+end);
    
    if(i==k){
        return i;
    }
    else if(i>k){
        return Select(array,start,i-1,k);
    }
    else{
        return Select(array,i+1,end,k);
    }
    

    }

    Select 将在数组中的第 k 个最小元素上分割数组;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 2010-09-14
      相关资源
      最近更新 更多